1 /* $NetBSD: esp_core.c,v 1.40.44.1 2010/11/21 20:13:01 riz Exp $ */
2 /* $KAME: esp_core.c,v 1.53 2001/11/27 09:47:30 sakane Exp $ */
3
4 /*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: esp_core.c,v 1.40.44.1 2010/11/21 20:13:01 riz Exp $");
35
36 #include "opt_inet.h"
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/malloc.h>
41 #include <sys/mbuf.h>
42 #include <sys/domain.h>
43 #include <sys/protosw.h>
44 #include <sys/socket.h>
45 #include <sys/errno.h>
46 #include <sys/time.h>
47 #include <sys/kernel.h>
48 #include <sys/syslog.h>
49
50 #include <net/if.h>
51 #include <net/route.h>
52
53 #include <netinet/in.h>
54
55 #include <netinet6/ipsec.h>
56 #include <netinet6/ah.h>
57 #include <netinet6/esp.h>
58 #include <netinet6/esp_rijndael.h>
59 #include <netinet6/esp_aesctr.h>
60 #include <net/pfkeyv2.h>
61 #include <netkey/key.h>
62
63 #include <crypto/des/des.h>
64 #include <crypto/blowfish/blowfish.h>
65 #include <crypto/cast128/cast128.h>
66
67 #include <net/net_osdep.h>
68
69 static int esp_null_mature __P((struct secasvar *));
70 static int esp_null_decrypt __P((struct mbuf *, size_t,
71 struct secasvar *, const struct esp_algorithm *, int));
72 static int esp_null_encrypt __P((struct mbuf *, size_t, size_t,
73 struct secasvar *, const struct esp_algorithm *, int));
74 static int esp_descbc_mature __P((struct secasvar *));
75 static int esp_descbc_ivlen __P((const struct esp_algorithm *,
76 struct secasvar *));
77 static int esp_des_schedule __P((const struct esp_algorithm *,
78 struct secasvar *));
79 static size_t esp_des_schedlen __P((const struct esp_algorithm *));
80 static int esp_des_blockdecrypt __P((const struct esp_algorithm *,
81 struct secasvar *, u_int8_t *, u_int8_t *));
82 static int esp_des_blockencrypt __P((const struct esp_algorithm *,
83 struct secasvar *, u_int8_t *, u_int8_t *));
84 static int esp_cbc_mature __P((struct secasvar *));
85 static int esp_blowfish_schedule __P((const struct esp_algorithm *,
86 struct secasvar *));
87 static size_t esp_blowfish_schedlen __P((const struct esp_algorithm *));
88 static int esp_blowfish_blockdecrypt __P((const struct esp_algorithm *,
89 struct secasvar *, u_int8_t *, u_int8_t *));
90 static int esp_blowfish_blockencrypt __P((const struct esp_algorithm *,
91 struct secasvar *, u_int8_t *, u_int8_t *));
92 static int esp_cast128_schedule __P((const struct esp_algorithm *,
93 struct secasvar *));
94 static size_t esp_cast128_schedlen __P((const struct esp_algorithm *));
95 static int esp_cast128_blockdecrypt __P((const struct esp_algorithm *,
96 struct secasvar *, u_int8_t *, u_int8_t *));
97 static int esp_cast128_blockencrypt __P((const struct esp_algorithm *,
98 struct secasvar *, u_int8_t *, u_int8_t *));
99 static int esp_3des_schedule __P((const struct esp_algorithm *,
100 struct secasvar *));
101 static size_t esp_3des_schedlen __P((const struct esp_algorithm *));
102 static int esp_3des_blockdecrypt __P((const struct esp_algorithm *,
103 struct secasvar *, u_int8_t *, u_int8_t *));
104 static int esp_3des_blockencrypt __P((const struct esp_algorithm *,
105 struct secasvar *, u_int8_t *, u_int8_t *));
106 static int esp_common_ivlen __P((const struct esp_algorithm *,
107 struct secasvar *));
108 static int esp_cbc_decrypt __P((struct mbuf *, size_t,
109 struct secasvar *, const struct esp_algorithm *, int));
110 static int esp_cbc_encrypt __P((struct mbuf *, size_t, size_t,
111 struct secasvar *, const struct esp_algorithm *, int));
112
113 #define MAXIVLEN 16
114
115 static const struct esp_algorithm esp_algorithms[] = {
116 { 8, -1, esp_descbc_mature, 64, 64, esp_des_schedlen,
117 "des-cbc",
118 esp_descbc_ivlen, esp_cbc_decrypt,
119 esp_cbc_encrypt, esp_des_schedule,
120 esp_des_blockdecrypt, esp_des_blockencrypt, },
121 { 8, 8, esp_cbc_mature, 192, 192, esp_3des_schedlen,
122 "3des-cbc",
123 esp_common_ivlen, esp_cbc_decrypt,
124 esp_cbc_encrypt, esp_3des_schedule,
125 esp_3des_blockdecrypt, esp_3des_blockencrypt, },
126 { 1, 0, esp_null_mature, 0, 2048, NULL,
127 "null",
128 esp_common_ivlen, esp_null_decrypt,
129 esp_null_encrypt, NULL,
130 NULL, NULL },
131 { 8, 8, esp_cbc_mature, 40, 448, esp_blowfish_schedlen, "blowfish-cbc",
132 esp_common_ivlen, esp_cbc_decrypt,
133 esp_cbc_encrypt, esp_blowfish_schedule,
134 esp_blowfish_blockdecrypt, esp_blowfish_blockencrypt, },
135 { 8, 8, esp_cbc_mature, 40, 128, esp_cast128_schedlen,
136 "cast128-cbc",
137 esp_common_ivlen, esp_cbc_decrypt,
138 esp_cbc_encrypt, esp_cast128_schedule,
139 esp_cast128_blockdecrypt, esp_cast128_blockencrypt, },
140 { 16, 16, esp_cbc_mature, 128, 256, esp_rijndael_schedlen,
141 "rijndael-cbc",
142 esp_common_ivlen, esp_cbc_decrypt,
143 esp_cbc_encrypt, esp_rijndael_schedule,
144 esp_rijndael_blockdecrypt, esp_rijndael_blockencrypt },
145 { 16, 8, esp_aesctr_mature, 160, 288, esp_aesctr_schedlen,
146 "aes-ctr",
147 esp_common_ivlen, esp_aesctr_decrypt,
148 esp_aesctr_encrypt, esp_aesctr_schedule,
149 NULL, NULL },
150 };
151
152 const struct esp_algorithm *
153 esp_algorithm_lookup(int idx)
154 {
155
156 switch (idx) {
157 case SADB_EALG_DESCBC:
158 return &esp_algorithms[0];
159 case SADB_EALG_3DESCBC:
160 return &esp_algorithms[1];
161 case SADB_EALG_NULL:
162 return &esp_algorithms[2];
163 case SADB_X_EALG_BLOWFISHCBC:
164 return &esp_algorithms[3];
165 case SADB_X_EALG_CAST128CBC:
166 return &esp_algorithms[4];
167 case SADB_X_EALG_RIJNDAELCBC:
168 return &esp_algorithms[5];
169 case SADB_X_EALG_AESCTR:
170 return &esp_algorithms[6];
171 default:
172 return NULL;
173 }
174 }
175
176 int
177 esp_max_padbound()
178 {
179 int idx;
180 static int padbound = 0;
181
182 if (padbound)
183 return padbound;
184
185 for (idx = 0; idx < sizeof(esp_algorithms)/sizeof(esp_algorithms[0]);
186 idx++) {
187 if (esp_algorithms[idx].padbound > padbound)
188 padbound = esp_algorithms[idx].padbound;
189 }
190 return padbound;
191 }
192
193 int
194 esp_max_ivlen()
195 {
196 int idx;
197 static int ivlen = 0;
198
199 if (ivlen)
200 return ivlen;
201
202 for (idx = 0; idx < sizeof(esp_algorithms)/sizeof(esp_algorithms[0]);
203 idx++) {
204 if (esp_algorithms[idx].ivlenval > ivlen)
205 ivlen = esp_algorithms[idx].ivlenval;
206 }
207 return ivlen;
208 }
209
210 int
211 esp_schedule(const struct esp_algorithm *algo, struct secasvar *sav)
212 {
213 int error;
214
215 /* check for key length */
216 if (_KEYBITS(sav->key_enc) < algo->keymin ||
217 _KEYBITS(sav->key_enc) > algo->keymax) {
218 ipseclog((LOG_ERR,
219 "esp_schedule %s: unsupported key length %d: "
220 "needs %d to %d bits\n", algo->name, _KEYBITS(sav->key_enc),
221 algo->keymin, algo->keymax));
222 return EINVAL;
223 }
224
225 /* already allocated */
226 if (sav->sched && sav->schedlen != 0)
227 return 0;
228 /* no schedule necessary */
229 if (!algo->schedule || !algo->schedlen)
230 return 0;
231
232 sav->schedlen = (*algo->schedlen)(algo);
233 sav->sched = malloc(sav->schedlen, M_SECA, M_DONTWAIT);
234 if (!sav->sched) {
235 sav->schedlen = 0;
236 return ENOBUFS;
237 }
238
239 error = (*algo->schedule)(algo, sav);
240 if (error) {
241 ipseclog((LOG_ERR, "esp_schedule %s: error %d\n",
242 algo->name, error));
243 bzero(sav->sched, sav->schedlen);
244 free(sav->sched, M_SECA);
245 sav->sched = NULL;
246 sav->schedlen = 0;
247 }
248 return error;
249 }
250
251 static int
252 esp_null_mature(struct secasvar *sav)
253 {
254
255 /* anything is okay */
256 return 0;
257 }
258
259 static int
260 esp_null_decrypt(
261 struct mbuf *m,
262 size_t off, /* offset to ESP header */
263 struct secasvar *sav,
264 const struct esp_algorithm *algo,
265 int ivlen
266 )
267 {
268
269 return 0; /* do nothing */
270 }
271
272 static int
273 esp_null_encrypt(
274 struct mbuf *m,
275 size_t off, /* offset to ESP header */
276 size_t plen, /* payload length (to be encrypted) */
277 struct secasvar *sav,
278 const struct esp_algorithm *algo,
279 int ivlen
280 )
281 {
282
283 return 0; /* do nothing */
284 }
285
286 static int
287 esp_descbc_mature(struct secasvar *sav)
288 {
289 const struct esp_algorithm *algo;
290
291 if (!(sav->flags & SADB_X_EXT_OLD) && (sav->flags & SADB_X_EXT_IV4B)) {
292 ipseclog((LOG_ERR, "esp_cbc_mature: "
293 "algorithm incompatible with 4 octets IV length\n"));
294 return 1;
295 }
296
297 if (!sav->key_enc) {
298 ipseclog((LOG_ERR, "esp_descbc_mature: no key is given.\n"));
299 return 1;
300 }
301
302 algo = esp_algorithm_lookup(sav->alg_enc);
303 if (!algo) {
304 ipseclog((LOG_ERR,
305 "esp_descbc_mature: unsupported algorithm.\n"));
306 return 1;
307 }
308
309 if (_KEYBITS(sav->key_enc) < algo->keymin ||
310 _KEYBITS(sav->key_enc) > algo->keymax) {
311 ipseclog((LOG_ERR,
312 "esp_descbc_mature: invalid key length %d.\n",
313 _KEYBITS(sav->key_enc)));
314 return 1;
315 }
316
317 /* weak key check */
318 if (des_is_weak_key((des_cblock *)_KEYBUF(sav->key_enc))) {
319 ipseclog((LOG_ERR,
320 "esp_descbc_mature: weak key was passed.\n"));
321 return 1;
322 }
323
324 return 0;
325 }
326
327 static int
328 esp_descbc_ivlen(const struct esp_algorithm *algo,
329 struct secasvar *sav)
330 {
331
332 if (!sav)
333 return 8;
334 if ((sav->flags & SADB_X_EXT_OLD) && (sav->flags & SADB_X_EXT_IV4B))
335 return 4;
336 if (!(sav->flags & SADB_X_EXT_OLD) && (sav->flags & SADB_X_EXT_DERIV))
337 return 4;
338 return 8;
339 }
340
341 static size_t
342 esp_des_schedlen(const struct esp_algorithm *algo)
343 {
344
345 return sizeof(des_key_schedule);
346 }
347
348 static int
349 esp_des_schedule(const struct esp_algorithm *algo,
350 struct secasvar *sav)
351 {
352
353 if (des_key_sched((des_cblock *)_KEYBUF(sav->key_enc),
354 *(des_key_schedule *)sav->sched))
355 return EINVAL;
356 else
357 return 0;
358 }
359
360 static int
361 esp_des_blockdecrypt( const struct esp_algorithm *algo,
362 struct secasvar *sav, u_int8_t *s, u_int8_t *d)
363 {
364
365 /* assumption: d has a good alignment */
366 bcopy(s, d, sizeof(DES_LONG) * 2);
367 des_ecb_encrypt((des_cblock *)d, (des_cblock *)d,
368 *(des_key_schedule *)sav->sched, DES_DECRYPT);
369 return 0;
370 }
371
372 static int
373 esp_des_blockencrypt(const struct esp_algorithm *algo,
374 struct secasvar *sav, u_int8_t *s, u_int8_t *d)
375 {
376
377 /* assumption: d has a good alignment */
378 bcopy(s, d, sizeof(DES_LONG) * 2);
379 des_ecb_encrypt((des_cblock *)d, (des_cblock *)d,
380 *(des_key_schedule *)sav->sched, DES_ENCRYPT);
381 return 0;
382 }
383
384 static int
385 esp_cbc_mature(struct secasvar *sav)
386 {
387 int keylen;
388 const struct esp_algorithm *algo;
389
390 if (sav->flags & SADB_X_EXT_OLD) {
391 ipseclog((LOG_ERR,
392 "esp_cbc_mature: algorithm incompatible with esp-old\n"));
393 return 1;
394 }
395 if (sav->flags & SADB_X_EXT_DERIV) {
396 ipseclog((LOG_ERR,
397 "esp_cbc_mature: algorithm incompatible with derived\n"));
398 return 1;
399 }
400
401 if (!sav->key_enc) {
402 ipseclog((LOG_ERR, "esp_cbc_mature: no key is given.\n"));
403 return 1;
404 }
405
406 algo = esp_algorithm_lookup(sav->alg_enc);
407 if (algo == NULL) {
408 ipseclog((LOG_ERR,
409 "esp_cbc_mature: unsupported encryption algorithm %d\n",
410 sav->alg_enc));
411 return 1;
412 }
413
414 keylen = sav->key_enc->sadb_key_bits;
415 if (keylen < algo->keymin || algo->keymax < keylen) {
416 ipseclog((LOG_ERR,
417 "esp_cbc_mature %s: invalid key length %d.\n",
418 algo->name, sav->key_enc->sadb_key_bits));
419 return 1;
420 }
421 switch (sav->alg_enc) {
422 case SADB_EALG_3DESCBC:
423 /* weak key check */
424 if (des_is_weak_key((des_cblock *)_KEYBUF(sav->key_enc)) ||
425 des_is_weak_key((des_cblock *)(_KEYBUF(sav->key_enc) + 8)) ||
426 des_is_weak_key((des_cblock *)(_KEYBUF(sav->key_enc) + 16))) {
427 ipseclog((LOG_ERR,
428 "esp_cbc_mature %s: weak key was passed.\n",
429 algo->name));
430 return 1;
431 }
432 break;
433 case SADB_X_EALG_BLOWFISHCBC:
434 case SADB_X_EALG_CAST128CBC:
435 break;
436 case SADB_X_EALG_RIJNDAELCBC:
437 /* allows specific key sizes only */
438 if (!(keylen == 128 || keylen == 192 || keylen == 256)) {
439 ipseclog((LOG_ERR,
440 "esp_cbc_mature %s: invalid key length %d.\n",
441 algo->name, keylen));
442 return 1;
443 }
444 break;
445 }
446
447 return 0;
448 }
449
450 static size_t
451 esp_blowfish_schedlen(const struct esp_algorithm *algo)
452 {
453
454 return sizeof(BF_KEY);
455 }
456
457 static int
458 esp_blowfish_schedule(const struct esp_algorithm *algo,
459 struct secasvar *sav)
460 {
461
462 BF_set_key((BF_KEY *)sav->sched, _KEYLEN(sav->key_enc),
463 _KEYBUF(sav->key_enc));
464 return 0;
465 }
466
467 static int
468 esp_blowfish_blockdecrypt(const struct esp_algorithm *algo,
469 struct secasvar *sav, u_int8_t *s, u_int8_t *d)
470 {
471
472 BF_ecb_encrypt(s, d, (BF_KEY *)sav->sched, 0);
473 return 0;
474 }
475
476 static int
477 esp_blowfish_blockencrypt(const struct esp_algorithm *algo,
478 struct secasvar *sav, u_int8_t *s, u_int8_t *d)
479 {
480
481 BF_ecb_encrypt(s, d, (BF_KEY *)sav->sched, 1);
482 return 0;
483 }
484
485 static size_t
486 esp_cast128_schedlen(const struct esp_algorithm *algo)
487 {
488
489 return sizeof(cast128_key);
490 }
491
492 static int
493 esp_cast128_schedule(const struct esp_algorithm *algo,
494 struct secasvar *sav)
495 {
496
497 cast128_setkey((cast128_key *)sav->sched, _KEYBUF(sav->key_enc),
498 _KEYLEN(sav->key_enc));
499 return 0;
500 }
501
502 static int
503 esp_cast128_blockdecrypt(const struct esp_algorithm *algo,
504 struct secasvar *sav, u_int8_t *s, u_int8_t *d)
505 {
506
507 cast128_decrypt((cast128_key *)sav->sched, s, d);
508 return 0;
509 }
510
511 static int
512 esp_cast128_blockencrypt(const struct esp_algorithm *algo,
513 struct secasvar *sav, u_int8_t *s, u_int8_t *d)
514 {
515
516 cast128_encrypt((cast128_key *)sav->sched, s, d);
517 return 0;
518 }
519
520 static size_t
521 esp_3des_schedlen(const struct esp_algorithm *algo)
522 {
523
524 return sizeof(des_key_schedule) * 3;
525 }
526
527 static int
528 esp_3des_schedule(const struct esp_algorithm *algo,
529 struct secasvar *sav)
530 {
531 int error;
532 des_key_schedule *p;
533 int i;
534 u_int8_t *k;
535
536 p = (des_key_schedule *)sav->sched;
537 k = _KEYBUF(sav->key_enc);
538 for (i = 0; i < 3; i++) {
539 error = des_key_sched((des_cblock *)(k + 8 * i), p[i]);
540 if (error)
541 return EINVAL;
542 }
543 return 0;
544 }
545
546 static int
547 esp_3des_blockdecrypt(const struct esp_algorithm *algo,
548 struct secasvar *sav, u_int8_t *s, u_int8_t *d)
549 {
550 des_key_schedule *p;
551
552 /* assumption: d has a good alignment */
553 p = (des_key_schedule *)sav->sched;
554 bcopy(s, d, sizeof(DES_LONG) * 2);
555 des_ecb3_encrypt((des_cblock *)d, (des_cblock *)d,
556 p[0], p[1], p[2], DES_DECRYPT);
557 return 0;
558 }
559
560 static int
561 esp_3des_blockencrypt(const struct esp_algorithm *algo,
562 struct secasvar *sav, u_int8_t *s, u_int8_t *d)
563 {
564 des_key_schedule *p;
565
566 /* assumption: d has a good alignment */
567 p = (des_key_schedule *)sav->sched;
568 bcopy(s, d, sizeof(DES_LONG) * 2);
569 des_ecb3_encrypt((des_cblock *)d, (des_cblock *)d,
570 p[0], p[1], p[2], DES_ENCRYPT);
571 return 0;
572 }
573
574 static int
575 esp_common_ivlen(const struct esp_algorithm *algo,
576 struct secasvar *sav)
577 {
578
579 if (!algo)
580 panic("esp_common_ivlen: unknown algorithm");
581 return algo->ivlenval;
582 }
583
584 static int
585 esp_cbc_decrypt(struct mbuf *m, size_t off, struct secasvar *sav,
586 const struct esp_algorithm *algo, int ivlen)
587 {
588 struct mbuf *s;
589 struct mbuf *d, *d0, *dp;
590 int soff, doff; /* offset from the head of chain, to head of this mbuf */
591 int sn, dn; /* offset from the head of the mbuf, to meat */
592 size_t ivoff, bodyoff;
593 u_int8_t iv[MAXIVLEN], *ivp;
594 u_int8_t sbuf[MAXIVLEN], *sp;
595 u_int8_t *p, *q;
596 struct mbuf *scut;
597 int scutoff;
598 int i;
599 int blocklen;
600
601 if (ivlen != sav->ivlen || ivlen > sizeof(iv)) {
602 ipseclog((LOG_ERR, "esp_cbc_decrypt %s: "
603 "unsupported ivlen %d\n", algo->name, ivlen));
604 m_freem(m);
605 return EINVAL;
606 }
607
608 /* assumes blocklen == padbound */
609 blocklen = algo->padbound;
610
611 #ifdef DIAGNOSTIC
612 if (blocklen > sizeof(iv)) {
613 ipseclog((LOG_ERR, "esp_cbc_decrypt %s: "
614 "unsupported blocklen %d\n", algo->name, blocklen));
615 m_freem(m);
616 return EINVAL;
617 }
618 #endif
619
620 if (sav->flags & SADB_X_EXT_OLD) {
621 /* RFC 1827 */
622 ivoff = off + sizeof(struct esp);
623 bodyoff = off + sizeof(struct esp) + ivlen;
624 } else {
625 /* RFC 2406 */
626 if (sav->flags & SADB_X_EXT_DERIV) {
627 /*
628 * draft-ietf-ipsec-ciph-des-derived-00.txt
629 * uses sequence number field as IV field.
630 */
631 ivoff = off + sizeof(struct esp);
632 bodyoff = off + sizeof(struct esp) + sizeof(u_int32_t);
633 ivlen = sizeof(u_int32_t);
634 } else {
635 ivoff = off + sizeof(struct newesp);
636 bodyoff = off + sizeof(struct newesp) + ivlen;
637 }
638 }
639
640 /* grab iv */
641 m_copydata(m, ivoff, ivlen, (void *)iv);
642
643 /* extend iv */
644 if (ivlen == blocklen)
645 ;
646 else if (ivlen == 4 && blocklen == 8) {
647 bcopy(&iv[0], &iv[4], 4);
648 iv[4] ^= 0xff;
649 iv[5] ^= 0xff;
650 iv[6] ^= 0xff;
651 iv[7] ^= 0xff;
652 } else {
653 ipseclog((LOG_ERR, "esp_cbc_encrypt %s: "
654 "unsupported ivlen/blocklen: %d %d\n",
655 algo->name, ivlen, blocklen));
656 m_freem(m);
657 return EINVAL;
658 }
659
660 if (m->m_pkthdr.len < bodyoff) {
661 ipseclog((LOG_ERR, "esp_cbc_decrypt %s: bad len %d/%lu\n",
662 algo->name, m->m_pkthdr.len, (unsigned long)bodyoff));
663 m_freem(m);
664 return EINVAL;
665 }
666 if ((m->m_pkthdr.len - bodyoff) % blocklen) {
667 ipseclog((LOG_ERR, "esp_cbc_decrypt %s: "
668 "payload length must be multiple of %d\n",
669 algo->name, blocklen));
670 m_freem(m);
671 return EINVAL;
672 }
673
674 s = m;
675 d = d0 = dp = NULL;
676 soff = doff = sn = dn = 0;
677 ivp = sp = NULL;
678
679 /* skip bodyoff */
680 while (soff < bodyoff) {
681 if (soff + s->m_len > bodyoff) {
682 sn = bodyoff - soff;
683 break;
684 }
685
686 soff += s->m_len;
687 s = s->m_next;
688 }
689 scut = s;
690 scutoff = sn;
691
692 /* skip over empty mbuf */
693 while (s && s->m_len == 0)
694 s = s->m_next;
695
696 while (soff < m->m_pkthdr.len) {
697 /* source */
698 if (sn + blocklen <= s->m_len) {
699 /* body is continuous */
700 sp = mtod(s, u_int8_t *) + sn;
701 } else {
702 /* body is non-continuous */
703 m_copydata(s, sn, blocklen, (void *)sbuf);
704 sp = sbuf;
705 }
706
707 /* destination */
708 if (!d || dn + blocklen > d->m_len) {
709 if (d)
710 dp = d;
711 MGET(d, M_DONTWAIT, MT_DATA);
712 i = m->m_pkthdr.len - (soff + sn);
713 if (d && i > MLEN) {
714 MCLGET(d, M_DONTWAIT);
715 if ((d->m_flags & M_EXT) == 0) {
716 m_free(d);
717 d = NULL;
718 }
719 }
720 if (!d) {
721 m_freem(m);
722 if (d0)
723 m_freem(d0);
724 return ENOBUFS;
725 }
726 if (!d0)
727 d0 = d;
728 if (dp)
729 dp->m_next = d;
730 d->m_len = 0;
731 d->m_len = (M_TRAILINGSPACE(d) / blocklen) * blocklen;
732 if (d->m_len > i)
733 d->m_len = i;
734 dn = 0;
735 }
736
737 /* decrypt */
738 (*algo->blockdecrypt)(algo, sav, sp, mtod(d, u_int8_t *) + dn);
739
740 /* xor */
741 p = ivp ? ivp : iv;
742 q = mtod(d, u_int8_t *) + dn;
743 for (i = 0; i < blocklen; i++)
744 q[i] ^= p[i];
745
746 /* next iv */
747 if (sp == sbuf) {
748 bcopy(sbuf, iv, blocklen);
749 ivp = NULL;
750 } else
751 ivp = sp;
752
753 sn += blocklen;
754 dn += blocklen;
755
756 /* find the next source block */
757 while (s && sn >= s->m_len) {
758 sn -= s->m_len;
759 soff += s->m_len;
760 s = s->m_next;
761 }
762
763 /* skip over empty mbuf */
764 while (s && s->m_len == 0)
765 s = s->m_next;
766 }
767
768 m_freem(scut->m_next);
769 scut->m_len = scutoff;
770 scut->m_next = d0;
771
772 /* just in case */
773 bzero(iv, sizeof(iv));
774 bzero(sbuf, sizeof(sbuf));
775
776 return 0;
777 }
778
779 static int
780 esp_cbc_encrypt(
781 struct mbuf *m,
782 size_t off,
783 size_t plen,
784 struct secasvar *sav,
785 const struct esp_algorithm *algo,
786 int ivlen
787 )
788 {
789 struct mbuf *s;
790 struct mbuf *d, *d0, *dp;
791 int soff, doff; /* offset from the head of chain, to head of this mbuf */
792 int sn, dn; /* offset from the head of the mbuf, to meat */
793 size_t ivoff, bodyoff;
794 u_int8_t iv[MAXIVLEN], *ivp;
795 u_int8_t sbuf[MAXIVLEN], *sp;
796 u_int8_t *p, *q;
797 struct mbuf *scut;
798 int scutoff;
799 int i;
800 int blocklen;
801 int derived;
802
803 if (ivlen != sav->ivlen || ivlen > sizeof(iv)) {
804 ipseclog((LOG_ERR, "esp_cbc_encrypt %s: "
805 "unsupported ivlen %d\n", algo->name, ivlen));
806 m_freem(m);
807 return EINVAL;
808 }
809
810 /* assumes blocklen == padbound */
811 blocklen = algo->padbound;
812
813 #ifdef DIAGNOSTIC
814 if (blocklen > sizeof(iv)) {
815 ipseclog((LOG_ERR, "esp_cbc_encrypt %s: "
816 "unsupported blocklen %d\n", algo->name, blocklen));
817 m_freem(m);
818 return EINVAL;
819 }
820 #endif
821
822 if (sav->flags & SADB_X_EXT_OLD) {
823 /* RFC 1827 */
824 ivoff = off + sizeof(struct esp);
825 bodyoff = off + sizeof(struct esp) + ivlen;
826 derived = 0;
827 } else {
828 /* RFC 2406 */
829 if (sav->flags & SADB_X_EXT_DERIV) {
830 /*
831 * draft-ietf-ipsec-ciph-des-derived-00.txt
832 * uses sequence number field as IV field.
833 */
834 ivoff = off + sizeof(struct esp);
835 bodyoff = off + sizeof(struct esp) + sizeof(u_int32_t);
836 ivlen = sizeof(u_int32_t);
837 derived = 1;
838 } else {
839 ivoff = off + sizeof(struct newesp);
840 bodyoff = off + sizeof(struct newesp) + ivlen;
841 derived = 0;
842 }
843 }
844
845 /* put iv into the packet. if we are in derived mode, use seqno. */
846 if (derived)
847 m_copydata(m, ivoff, ivlen, (void *)iv);
848 else {
849 bcopy(sav->iv, iv, ivlen);
850 /* maybe it is better to overwrite dest, not source */
851 m_copyback(m, ivoff, ivlen, (void *)iv);
852 }
853
854 /* extend iv */
855 if (ivlen == blocklen)
856 ;
857 else if (ivlen == 4 && blocklen == 8) {
858 bcopy(&iv[0], &iv[4], 4);
859 iv[4] ^= 0xff;
860 iv[5] ^= 0xff;
861 iv[6] ^= 0xff;
862 iv[7] ^= 0xff;
863 } else {
864 ipseclog((LOG_ERR, "esp_cbc_encrypt %s: "
865 "unsupported ivlen/blocklen: %d %d\n",
866 algo->name, ivlen, blocklen));
867 m_freem(m);
868 return EINVAL;
869 }
870
871 if (m->m_pkthdr.len < bodyoff) {
872 ipseclog((LOG_ERR, "esp_cbc_encrypt %s: bad len %d/%lu\n",
873 algo->name, m->m_pkthdr.len, (unsigned long)bodyoff));
874 m_freem(m);
875 return EINVAL;
876 }
877 if ((m->m_pkthdr.len - bodyoff) % blocklen) {
878 ipseclog((LOG_ERR, "esp_cbc_encrypt %s: "
879 "payload length must be multiple of %lu\n",
880 algo->name, (unsigned long)algo->padbound));
881 m_freem(m);
882 return EINVAL;
883 }
884
885 s = m;
886 d = d0 = dp = NULL;
887 soff = doff = sn = dn = 0;
888 ivp = sp = NULL;
889
890 /* skip bodyoff */
891 while (soff < bodyoff) {
892 if (soff + s->m_len > bodyoff) {
893 sn = bodyoff - soff;
894 break;
895 }
896
897 soff += s->m_len;
898 s = s->m_next;
899 }
900 scut = s;
901 scutoff = sn;
902
903 /* skip over empty mbuf */
904 while (s && s->m_len == 0)
905 s = s->m_next;
906
907 while (soff < m->m_pkthdr.len) {
908 /* source */
909 if (sn + blocklen <= s->m_len) {
910 /* body is continuous */
911 sp = mtod(s, u_int8_t *) + sn;
912 } else {
913 /* body is non-continuous */
914 m_copydata(s, sn, blocklen, (void *)sbuf);
915 sp = sbuf;
916 }
917
918 /* destination */
919 if (!d || dn + blocklen > d->m_len) {
920 if (d)
921 dp = d;
922 MGET(d, M_DONTWAIT, MT_DATA);
923 i = m->m_pkthdr.len - (soff + sn);
924 if (d && i > MLEN) {
925 MCLGET(d, M_DONTWAIT);
926 if ((d->m_flags & M_EXT) == 0) {
927 m_free(d);
928 d = NULL;
929 }
930 }
931 if (!d) {
932 m_freem(m);
933 if (d0)
934 m_freem(d0);
935 return ENOBUFS;
936 }
937 if (!d0)
938 d0 = d;
939 if (dp)
940 dp->m_next = d;
941 d->m_len = 0;
942 d->m_len = (M_TRAILINGSPACE(d) / blocklen) * blocklen;
943 if (d->m_len > i)
944 d->m_len = i;
945 dn = 0;
946 }
947
948 /* xor */
949 p = ivp ? ivp : iv;
950 q = sp;
951 for (i = 0; i < blocklen; i++)
952 q[i] ^= p[i];
953
954 /* encrypt */
955 (*algo->blockencrypt)(algo, sav, sp, mtod(d, u_int8_t *) + dn);
956
957 /* next iv */
958 ivp = mtod(d, u_int8_t *) + dn;
959
960 sn += blocklen;
961 dn += blocklen;
962
963 /* find the next source block */
964 while (s && sn >= s->m_len) {
965 sn -= s->m_len;
966 soff += s->m_len;
967 s = s->m_next;
968 }
969
970 /* skip over empty mbuf */
971 while (s && s->m_len == 0)
972 s = s->m_next;
973 }
974
975 m_freem(scut->m_next);
976 scut->m_len = scutoff;
977 scut->m_next = d0;
978
979 /* just in case */
980 bzero(iv, sizeof(iv));
981 bzero(sbuf, sizeof(sbuf));
982
983 key_sa_stir_iv(sav);
984
985 return 0;
986 }
987
988 /*------------------------------------------------------------*/
989
990 /* does not free m0 on error
991 *
992 * skip - offset to ESP header
993 * length - payloadd length
994 */
995 int
996 esp_auth(struct mbuf *m0, size_t skip, size_t length,
997 struct secasvar *sav, u_char *sum)
998 {
999 struct mbuf *m;
1000 size_t off;
1001 struct ah_algorithm_state s;
1002 u_char sumbuf[AH_MAXSUMSIZE];
1003 const struct ah_algorithm *algo;
1004 size_t siz;
1005 int error;
1006
1007 /* sanity checks */
1008 if (m0->m_pkthdr.len < skip) {
1009 ipseclog((LOG_DEBUG, "esp_auth: mbuf length < skip\n"));
1010 return EINVAL;
1011 }
1012 if (m0->m_pkthdr.len < skip + length) {
1013 ipseclog((LOG_DEBUG,
1014 "esp_auth: mbuf length < skip + length\n"));
1015 return EINVAL;
1016 }
1017 /*
1018 * length of esp part (excluding authentication data) must be 4n,
1019 * since nexthdr must be at offset 4n+3.
1020 */
1021 if (length % 4) {
1022 ipseclog((LOG_ERR, "esp_auth: length is not multiple of 4\n"));
1023 return EINVAL;
1024 }
1025 if (!sav) {
1026 ipseclog((LOG_DEBUG, "esp_auth: NULL SA passed\n"));
1027 return EINVAL;
1028 }
1029 algo = ah_algorithm_lookup(sav->alg_auth);
1030 if (!algo) {
1031 ipseclog((LOG_ERR,
1032 "esp_auth: bad ESP auth algorithm passed: %d\n",
1033 sav->alg_auth));
1034 return EINVAL;
1035 }
1036
1037 m = m0;
1038 off = 0;
1039
1040 siz = (((*algo->sumsiz)(sav) + 3) & ~(4 - 1));
1041 if (sizeof(sumbuf) < siz) {
1042 ipseclog((LOG_DEBUG,
1043 "esp_auth: AH_MAXSUMSIZE is too small: siz=%lu\n",
1044 (u_long)siz));
1045 return EINVAL;
1046 }
1047
1048 /* skip the header */
1049 while (skip) {
1050 if (!m)
1051 panic("mbuf chain?");
1052 if (m->m_len <= skip) {
1053 skip -= m->m_len;
1054 m = m->m_next;
1055 off = 0;
1056 } else {
1057 off = skip;
1058 skip = 0;
1059 }
1060 }
1061
1062 error = (*algo->init)(&s, sav);
1063 if (error)
1064 return error;
1065
1066 while (0 < length) {
1067 if (!m)
1068 panic("mbuf chain?");
1069
1070 if (m->m_len - off < length) {
1071 (*algo->update)(&s, mtod(m, u_char *) + off,
1072 m->m_len - off);
1073 length -= m->m_len - off;
1074 m = m->m_next;
1075 off = 0;
1076 } else {
1077 (*algo->update)(&s, mtod(m, u_char *) + off, length);
1078 break;
1079 }
1080 }
1081 (*algo->result)(&s, sumbuf, sizeof(sumbuf));
1082 bcopy(sumbuf, sum, siz); /* XXX */
1083
1084 return 0;
1085 }
Cache object: aef0e1ac840ebb4858fd886b25ceabc5
|