1 /*      $FreeBSD: src/sys/netinet6/esp_core.c,v 1.1.2.2 2001/07/03 11:01:49 ume Exp $   */ 
   2 /*      $KAME: esp_core.c,v 1.50 2000/11/02 12:27:38 itojun Exp $       */ 
   5  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 
   8  * Redistribution and use in source and binary forms, with or without 
   9  * modification, are permitted provided that the following conditions 
  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. 
  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 
  35 #include <sys/param.h> 
  36 #include <sys/systm.h> 
  37 #include <sys/malloc.h> 
  39 #include <sys/domain.h> 
  40 #include <sys/protosw.h> 
  41 #include <sys/socket.h> 
  42 #include <sys/errno.h> 
  44 #include <sys/kernel.h> 
  45 #include <sys/syslog.h> 
  48 #include <net/route.h> 
  50 #include <netinet/in.h> 
  51 #include <netinet/in_var.h> 
  53 #include <netinet/ip6.h> 
  54 #include <netinet6/ip6_var.h> 
  55 #include <netinet/icmp6.h> 
  58 #include <netinet6/ipsec.h> 
  60 #include <netinet6/ipsec6.h> 
  62 #include <netinet6/ah.h> 
  64 #include <netinet6/ah6.h> 
  66 #include <netinet6/esp.h> 
  68 #include <netinet6/esp6.h> 
  70 #include <netinet6/esp_rijndael.h> 
  71 #include <net/pfkeyv2.h> 
  72 #include <netkey/keydb.h> 
  73 #include <netkey/key.h> 
  74 #include <crypto/des/des.h> 
  75 #include <crypto/blowfish/blowfish.h> 
  76 #include <crypto/cast128/cast128.h> 
  78 #include <net/net_osdep.h> 
  80 static int esp_null_mature 
__P((struct secasvar 
*)); 
  81 static int esp_null_decrypt 
__P((struct mbuf 
*, size_t, 
  82         struct secasvar 
*, const struct esp_algorithm 
*, int)); 
  83 static int esp_null_encrypt 
__P((struct mbuf 
*, size_t, size_t, 
  84         struct secasvar 
*, const struct esp_algorithm 
*, int)); 
  85 static int esp_descbc_mature 
__P((struct secasvar 
*)); 
  86 static int esp_descbc_ivlen 
__P((const struct esp_algorithm 
*, 
  88 static int esp_des_schedule 
__P((const struct esp_algorithm 
*, 
  90 static int esp_des_schedlen 
__P((const struct esp_algorithm 
*)); 
  91 static int esp_des_blockdecrypt 
__P((const struct esp_algorithm 
*, 
  92         struct secasvar 
*, u_int8_t 
*, u_int8_t 
*)); 
  93 static int esp_des_blockencrypt 
__P((const struct esp_algorithm 
*, 
  94         struct secasvar 
*, u_int8_t 
*, u_int8_t 
*)); 
  95 static int esp_cbc_mature 
__P((struct secasvar 
*)); 
  96 static int esp_blowfish_schedule 
__P((const struct esp_algorithm 
*, 
  98 static int esp_blowfish_schedlen 
__P((const struct esp_algorithm 
*)); 
  99 static int esp_blowfish_blockdecrypt 
__P((const struct esp_algorithm 
*, 
 100         struct secasvar 
*, u_int8_t 
*, u_int8_t 
*)); 
 101 static int esp_blowfish_blockencrypt 
__P((const struct esp_algorithm 
*, 
 102         struct secasvar 
*, u_int8_t 
*, u_int8_t 
*)); 
 103 static int esp_cast128_schedule 
__P((const struct esp_algorithm 
*, 
 105 static int esp_cast128_schedlen 
__P((const struct esp_algorithm 
*)); 
 106 static int esp_cast128_blockdecrypt 
__P((const struct esp_algorithm 
*, 
 107         struct secasvar 
*, u_int8_t 
*, u_int8_t 
*)); 
 108 static int esp_cast128_blockencrypt 
__P((const struct esp_algorithm 
*, 
 109         struct secasvar 
*, u_int8_t 
*, u_int8_t 
*)); 
 110 static int esp_3des_schedule 
__P((const struct esp_algorithm 
*, 
 112 static int esp_3des_schedlen 
__P((const struct esp_algorithm 
*)); 
 113 static int esp_3des_blockdecrypt 
__P((const struct esp_algorithm 
*, 
 114         struct secasvar 
*, u_int8_t 
*, u_int8_t 
*)); 
 115 static int esp_3des_blockencrypt 
__P((const struct esp_algorithm 
*, 
 116         struct secasvar 
*, u_int8_t 
*, u_int8_t 
*)); 
 117 static int esp_common_ivlen 
__P((const struct esp_algorithm 
*, 
 119 static int esp_cbc_decrypt 
__P((struct mbuf 
*, size_t, 
 120         struct secasvar 
*, const struct esp_algorithm 
*, int)); 
 121 static int esp_cbc_encrypt 
__P((struct mbuf 
*, size_t, size_t, 
 122         struct secasvar 
*, const struct esp_algorithm 
*, int)); 
 126 static const struct esp_algorithm esp_algorithms
[] = { 
 127         { 8, -1, esp_descbc_mature
, 64, 64, esp_des_schedlen
, 
 129                 esp_descbc_ivlen
, esp_cbc_decrypt
, 
 130                 esp_cbc_encrypt
, esp_des_schedule
, 
 131                 esp_des_blockdecrypt
, esp_des_blockencrypt
, }, 
 132         { 8, 8, esp_cbc_mature
, 192, 192, esp_3des_schedlen
, 
 134                 esp_common_ivlen
, esp_cbc_decrypt
, 
 135                 esp_cbc_encrypt
, esp_3des_schedule
, 
 136                 esp_3des_blockdecrypt
, esp_3des_blockencrypt
, }, 
 137         { 1, 0, esp_null_mature
, 0, 2048, 0, "null", 
 138                 esp_common_ivlen
, esp_null_decrypt
, 
 139                 esp_null_encrypt
, NULL
, }, 
 140         { 8, 8, esp_cbc_mature
, 40, 448, esp_blowfish_schedlen
, "blowfish-cbc", 
 141                 esp_common_ivlen
, esp_cbc_decrypt
, 
 142                 esp_cbc_encrypt
, esp_blowfish_schedule
, 
 143                 esp_blowfish_blockdecrypt
, esp_blowfish_blockencrypt
, }, 
 144         { 8, 8, esp_cbc_mature
, 40, 128, esp_cast128_schedlen
, 
 146                 esp_common_ivlen
, esp_cbc_decrypt
, 
 147                 esp_cbc_encrypt
, esp_cast128_schedule
, 
 148                 esp_cast128_blockdecrypt
, esp_cast128_blockencrypt
, }, 
 149         { 16, 16, esp_cbc_mature
, 128, 256, esp_rijndael_schedlen
, 
 151                 esp_common_ivlen
, esp_cbc_decrypt
, 
 152                 esp_cbc_encrypt
, esp_rijndael_schedule
, 
 153                 esp_rijndael_blockdecrypt
, esp_rijndael_blockencrypt 
}, 
 156 const struct esp_algorithm 
* 
 157 esp_algorithm_lookup(idx
) 
 162         case SADB_EALG_DESCBC
: 
 163                 return &esp_algorithms
[0]; 
 164         case SADB_EALG_3DESCBC
: 
 165                 return &esp_algorithms
[1]; 
 167                 return &esp_algorithms
[2]; 
 168         case SADB_X_EALG_BLOWFISHCBC
: 
 169                 return &esp_algorithms
[3]; 
 170         case SADB_X_EALG_CAST128CBC
: 
 171                 return &esp_algorithms
[4]; 
 172         case SADB_X_EALG_RIJNDAELCBC
: 
 173                 return &esp_algorithms
[5]; 
 186         for (idx 
= 0; idx 
< sizeof(esp_algorithms
)/sizeof(esp_algorithms
[0]); 
 188                 if (esp_algorithms
[idx
].ivlenval 
> ivlen
) 
 189                         ivlen 
= esp_algorithms
[idx
].ivlenval
; 
 196 esp_schedule(algo
, sav
) 
 197         const struct esp_algorithm 
*algo
; 
 198         struct secasvar 
*sav
; 
 202         /* check for key length */ 
 203         if (_KEYBITS(sav
->key_enc
) < algo
->keymin 
|| 
 204             _KEYBITS(sav
->key_enc
) > algo
->keymax
) { 
 206                     "esp_schedule %s: unsupported key length %d: " 
 207                     "needs %d to %d bits\n", algo
->name
, _KEYBITS(sav
->key_enc
), 
 208                     algo
->keymin
, algo
->keymax
)); 
 212         /* already allocated */ 
 213         if (sav
->sched 
&& sav
->schedlen 
!= 0) 
 215         /* no schedule necessary */ 
 216         if (!algo
->schedule 
|| !algo
->schedlen
) 
 219         sav
->schedlen 
= (*algo
->schedlen
)(algo
); 
 220         if (sav
->schedlen 
< 0) 
 222         sav
->sched 
= _MALLOC(sav
->schedlen
, M_SECA
, M_DONTWAIT
); 
 228         error 
= (*algo
->schedule
)(algo
, sav
); 
 230                 ipseclog((LOG_ERR
, "esp_schedule %s: error %d\n", 
 232                 FREE(sav
->sched
, M_SECA
); 
 241         struct secasvar 
*sav
; 
 244         /* anything is okay */ 
 249 esp_null_decrypt(m
, off
, sav
, algo
, ivlen
) 
 251         size_t off
;             /* offset to ESP header */ 
 252         struct secasvar 
*sav
; 
 253         const struct esp_algorithm 
*algo
; 
 257         return 0; /* do nothing */ 
 261 esp_null_encrypt(m
, off
, plen
, sav
, algo
, ivlen
) 
 263         size_t off
;     /* offset to ESP header */ 
 264         size_t plen
;    /* payload length (to be encrypted) */ 
 265         struct secasvar 
*sav
; 
 266         const struct esp_algorithm 
*algo
; 
 270         return 0; /* do nothing */ 
 274 esp_descbc_mature(sav
) 
 275         struct secasvar 
*sav
; 
 277         const struct esp_algorithm 
*algo
; 
 279         if (!(sav
->flags 
& SADB_X_EXT_OLD
) && (sav
->flags 
& SADB_X_EXT_IV4B
)) { 
 280                 ipseclog((LOG_ERR
, "esp_cbc_mature: " 
 281                     "algorithm incompatible with 4 octets IV length\n")); 
 286                 ipseclog((LOG_ERR
, "esp_descbc_mature: no key is given.\n")); 
 290         algo 
= esp_algorithm_lookup(sav
->alg_enc
); 
 293                     "esp_descbc_mature: unsupported algorithm.\n")); 
 297         if (_KEYBITS(sav
->key_enc
) < algo
->keymin 
|| 
 298             _KEYBITS(sav
->key_enc
) > algo
->keymax
) { 
 300                     "esp_descbc_mature: invalid key length %d.\n", 
 301                     _KEYBITS(sav
->key_enc
))); 
 306         if (des_is_weak_key((des_cblock 
*)_KEYBUF(sav
->key_enc
))) { 
 308                     "esp_descbc_mature: weak key was passed.\n")); 
 316 esp_descbc_ivlen(algo
, sav
) 
 317         const struct esp_algorithm 
*algo
; 
 318         struct secasvar 
*sav
; 
 323         if ((sav
->flags 
& SADB_X_EXT_OLD
) && (sav
->flags 
& SADB_X_EXT_IV4B
)) 
 325         if (!(sav
->flags 
& SADB_X_EXT_OLD
) && (sav
->flags 
& SADB_X_EXT_DERIV
)) 
 331 esp_des_schedlen(algo
) 
 332         const struct esp_algorithm 
*algo
; 
 335         return sizeof(des_key_schedule
); 
 339 esp_des_schedule(algo
, sav
) 
 340         const struct esp_algorithm 
*algo
; 
 341         struct secasvar 
*sav
; 
 344         if (des_key_sched((des_cblock 
*)_KEYBUF(sav
->key_enc
), 
 345             *(des_key_schedule 
*)sav
->sched
)) 
 352 esp_des_blockdecrypt(algo
, sav
, s
, d
) 
 353         const struct esp_algorithm 
*algo
; 
 354         struct secasvar 
*sav
; 
 359         /* assumption: d has a good alignment */ 
 360         bcopy(s
, d
, sizeof(DES_LONG
) * 2); 
 361         des_ecb_encrypt((des_cblock 
*)d
, (des_cblock 
*)d
, 
 362             *(des_key_schedule 
*)sav
->sched
, DES_DECRYPT
); 
 367 esp_des_blockencrypt(algo
, sav
, s
, d
) 
 368         const struct esp_algorithm 
*algo
; 
 369         struct secasvar 
*sav
; 
 374         /* assumption: d has a good alignment */ 
 375         bcopy(s
, d
, sizeof(DES_LONG
) * 2); 
 376         des_ecb_encrypt((des_cblock 
*)d
, (des_cblock 
*)d
, 
 377             *(des_key_schedule 
*)sav
->sched
, DES_ENCRYPT
); 
 383         struct secasvar 
*sav
; 
 386         const struct esp_algorithm 
*algo
; 
 388         if (sav
->flags 
& SADB_X_EXT_OLD
) { 
 390                     "esp_cbc_mature: algorithm incompatible with esp-old\n")); 
 393         if (sav
->flags 
& SADB_X_EXT_DERIV
) { 
 395                     "esp_cbc_mature: algorithm incompatible with derived\n")); 
 400                 ipseclog((LOG_ERR
, "esp_cbc_mature: no key is given.\n")); 
 404         algo 
= esp_algorithm_lookup(sav
->alg_enc
); 
 407                     "esp_cbc_mature %s: unsupported algorithm.\n", algo
->name
)); 
 411         keylen 
= sav
->key_enc
->sadb_key_bits
; 
 412         if (keylen 
< algo
->keymin 
|| algo
->keymax 
< keylen
) { 
 414                     "esp_cbc_mature %s: invalid key length %d.\n", 
 415                     algo
->name
, sav
->key_enc
->sadb_key_bits
)); 
 418         switch (sav
->alg_enc
) { 
 419         case SADB_EALG_3DESCBC
: 
 421                 if (des_is_weak_key((des_cblock 
*)_KEYBUF(sav
->key_enc
)) || 
 422                     des_is_weak_key((des_cblock 
*)(_KEYBUF(sav
->key_enc
) + 8)) || 
 423                     des_is_weak_key((des_cblock 
*)(_KEYBUF(sav
->key_enc
) + 16))) { 
 425                             "esp_cbc_mature %s: weak key was passed.\n", 
 430         case SADB_X_EALG_BLOWFISHCBC
: 
 431         case SADB_X_EALG_CAST128CBC
: 
 433         case SADB_X_EALG_RIJNDAELCBC
: 
 434                 /* allows specific key sizes only */ 
 435                 if (!(keylen 
== 128 || keylen 
== 192 || keylen 
== 256)) { 
 437                             "esp_cbc_mature %s: invalid key length %d.\n", 
 438                             algo
->name
, keylen
)); 
 448 esp_blowfish_schedlen(algo
) 
 449         const struct esp_algorithm 
*algo
; 
 452         return sizeof(BF_KEY
); 
 456 esp_blowfish_schedule(algo
, sav
) 
 457         const struct esp_algorithm 
*algo
; 
 458         struct secasvar 
*sav
; 
 461         BF_set_key((BF_KEY 
*)sav
->sched
, _KEYLEN(sav
->key_enc
), 
 462             _KEYBUF(sav
->key_enc
)); 
 467 esp_blowfish_blockdecrypt(algo
, sav
, s
, d
) 
 468         const struct esp_algorithm 
*algo
; 
 469         struct secasvar 
*sav
; 
 473         /* HOLY COW!  BF_encrypt() takes values in host byteorder */ 
 476         bcopy(s
, t
, sizeof(t
)); 
 479         BF_encrypt(t
, (BF_KEY 
*)sav
->sched
, BF_DECRYPT
); 
 482         bcopy(t
, d
, sizeof(t
)); 
 487 esp_blowfish_blockencrypt(algo
, sav
, s
, d
) 
 488         const struct esp_algorithm 
*algo
; 
 489         struct secasvar 
*sav
; 
 493         /* HOLY COW!  BF_encrypt() takes values in host byteorder */ 
 496         bcopy(s
, t
, sizeof(t
)); 
 499         BF_encrypt(t
, (BF_KEY 
*)sav
->sched
, BF_ENCRYPT
); 
 502         bcopy(t
, d
, sizeof(t
)); 
 507 esp_cast128_schedlen(algo
) 
 508         const struct esp_algorithm 
*algo
; 
 511         return sizeof(u_int32_t
) * 32; 
 515 esp_cast128_schedule(algo
, sav
) 
 516         const struct esp_algorithm 
*algo
; 
 517         struct secasvar 
*sav
; 
 520         set_cast128_subkey((u_int32_t 
*)sav
->sched
, _KEYBUF(sav
->key_enc
), 
 521                 _KEYLEN(sav
->key_enc
)); 
 526 esp_cast128_blockdecrypt(algo
, sav
, s
, d
) 
 527         const struct esp_algorithm 
*algo
; 
 528         struct secasvar 
*sav
; 
 533         if (_KEYLEN(sav
->key_enc
) <= 80 / 8) 
 534                 cast128_decrypt_round12(d
, s
, (u_int32_t 
*)sav
->sched
); 
 536                 cast128_decrypt_round16(d
, s
, (u_int32_t 
*)sav
->sched
); 
 541 esp_cast128_blockencrypt(algo
, sav
, s
, d
) 
 542         const struct esp_algorithm 
*algo
; 
 543         struct secasvar 
*sav
; 
 548         if (_KEYLEN(sav
->key_enc
) <= 80 / 8) 
 549                 cast128_encrypt_round12(d
, s
, (u_int32_t 
*)sav
->sched
); 
 551                 cast128_encrypt_round16(d
, s
, (u_int32_t 
*)sav
->sched
); 
 556 esp_3des_schedlen(algo
) 
 557         const struct esp_algorithm 
*algo
; 
 560         return sizeof(des_key_schedule
) * 3; 
 564 esp_3des_schedule(algo
, sav
) 
 565         const struct esp_algorithm 
*algo
; 
 566         struct secasvar 
*sav
; 
 573         p 
= (des_key_schedule 
*)sav
->sched
; 
 574         k 
= _KEYBUF(sav
->key_enc
); 
 575         for (i 
= 0; i 
< 3; i
++) { 
 576                 error 
= des_key_sched((des_cblock 
*)(k 
+ 8 * i
), p
[i
]); 
 584 esp_3des_blockdecrypt(algo
, sav
, s
, d
) 
 585         const struct esp_algorithm 
*algo
; 
 586         struct secasvar 
*sav
; 
 592         /* assumption: d has a good alignment */ 
 593         p 
= (des_key_schedule 
*)sav
->sched
; 
 594         bcopy(s
, d
, sizeof(DES_LONG
) * 2); 
 595         des_ecb_encrypt((des_cblock 
*)d
, (des_cblock 
*)d
, p
[2], DES_DECRYPT
); 
 596         des_ecb_encrypt((des_cblock 
*)d
, (des_cblock 
*)d
, p
[1], DES_ENCRYPT
); 
 597         des_ecb_encrypt((des_cblock 
*)d
, (des_cblock 
*)d
, p
[0], DES_DECRYPT
); 
 602 esp_3des_blockencrypt(algo
, sav
, s
, d
) 
 603         const struct esp_algorithm 
*algo
; 
 604         struct secasvar 
*sav
; 
 610         /* assumption: d has a good alignment */ 
 611         p 
= (des_key_schedule 
*)sav
->sched
; 
 612         bcopy(s
, d
, sizeof(DES_LONG
) * 2); 
 613         des_ecb_encrypt((des_cblock 
*)d
, (des_cblock 
*)d
, p
[0], DES_ENCRYPT
); 
 614         des_ecb_encrypt((des_cblock 
*)d
, (des_cblock 
*)d
, p
[1], DES_DECRYPT
); 
 615         des_ecb_encrypt((des_cblock 
*)d
, (des_cblock 
*)d
, p
[2], DES_ENCRYPT
); 
 620 esp_common_ivlen(algo
, sav
) 
 621         const struct esp_algorithm 
*algo
; 
 622         struct secasvar 
*sav
; 
 626                 panic("esp_common_ivlen: unknown algorithm"); 
 627         return algo
->ivlenval
; 
 631 esp_cbc_decrypt(m
, off
, sav
, algo
, ivlen
) 
 634         struct secasvar 
*sav
; 
 635         const struct esp_algorithm 
*algo
; 
 639         struct mbuf 
*d
, *d0
, *dp
; 
 640         int soff
, doff
; /*offset from the head of chain, to head of this mbuf */ 
 641         int sn
, dn
;     /*offset from the head of the mbuf, to meat */ 
 642         size_t ivoff
, bodyoff
; 
 643         u_int8_t iv
[MAXIVLEN
], *ivp
; 
 644         u_int8_t sbuf
[MAXIVLEN
], *sp
; 
 652         if (ivlen 
!= sav
->ivlen 
|| ivlen 
> sizeof(iv
)) { 
 653                 ipseclog((LOG_ERR
, "esp_cbc_decrypt %s: " 
 654                     "unsupported ivlen %d\n", algo
->name
, ivlen
)); 
 659         /* assumes blocklen == padbound */ 
 660         blocklen 
= algo
->padbound
; 
 663         if (blocklen 
> sizeof(iv
)) { 
 664                 ipseclog((LOG_ERR
, "esp_cbc_decrypt %s: " 
 665                     "unsupported blocklen %d\n", algo
->name
, blocklen
)); 
 671         if (sav
->flags 
& SADB_X_EXT_OLD
) { 
 673                 ivoff 
= off 
+ sizeof(struct esp
); 
 674                 bodyoff 
= off 
+ sizeof(struct esp
) + ivlen
; 
 678                 if (sav
->flags 
& SADB_X_EXT_DERIV
) { 
 680                          * draft-ietf-ipsec-ciph-des-derived-00.txt 
 681                          * uses sequence number field as IV field. 
 683                         ivoff 
= off 
+ sizeof(struct esp
); 
 684                         bodyoff 
= off 
+ sizeof(struct esp
) + sizeof(u_int32_t
); 
 685                         ivlen 
= sizeof(u_int32_t
); 
 688                         ivoff 
= off 
+ sizeof(struct newesp
); 
 689                         bodyoff 
= off 
+ sizeof(struct newesp
) + ivlen
; 
 695         m_copydata(m
, ivoff
, ivlen
, iv
); 
 698         if (ivlen 
== blocklen
) 
 700         else if (ivlen 
== 4 && blocklen 
== 8) { 
 701                 bcopy(&iv
[0], &iv
[4], 4); 
 707                 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: " 
 708                     "unsupported ivlen/blocklen: %d %d\n", 
 709                     algo
->name
, ivlen
, blocklen
)); 
 714         if (m
->m_pkthdr
.len 
< bodyoff
) { 
 715                 ipseclog((LOG_ERR
, "esp_cbc_decrypt %s: bad len %d/%lu\n", 
 716                     algo
->name
, m
->m_pkthdr
.len
, (unsigned long)bodyoff
)); 
 720         if ((m
->m_pkthdr
.len 
- bodyoff
) % blocklen
) { 
 721                 ipseclog((LOG_ERR
, "esp_cbc_decrypt %s: " 
 722                     "payload length must be multiple of %d\n", 
 723                     algo
->name
, blocklen
)); 
 730         soff 
= doff 
= sn 
= dn 
= 0; 
 734         while (soff 
< bodyoff
) { 
 735                 if (soff 
+ s
->m_len 
> bodyoff
) { 
 746         /* skip over empty mbuf */ 
 747         while (s 
&& s
->m_len 
== 0) 
 750         while (soff 
< m
->m_pkthdr
.len
) { 
 752                 if (sn 
+ blocklen 
<= s
->m_len
) { 
 753                         /* body is continuous */ 
 754                         sp 
= mtod(s
, u_int8_t 
*) + sn
; 
 756                         /* body is non-continuous */ 
 757                         m_copydata(s
, sn
, blocklen
, sbuf
); 
 762                 if (!d 
|| dn 
+ blocklen 
> d
->m_len
) { 
 765                         MGET(d
, M_DONTWAIT
, MT_DATA
); 
 766                         i 
= m
->m_pkthdr
.len 
- (soff 
+ sn
); 
 768                                 MCLGET(d
, M_DONTWAIT
); 
 769                                 if ((d
->m_flags 
& M_EXT
) == 0) { 
 785                         d
->m_len 
= (M_TRAILINGSPACE(d
) / blocklen
) * blocklen
; 
 792                 (*algo
->blockdecrypt
)(algo
, sav
, sp
, mtod(d
, u_int8_t 
*) + dn
); 
 796                 q 
= mtod(d
, u_int8_t 
*) + dn
; 
 797                 for (i 
= 0; i 
< blocklen
; i
++) 
 802                         bcopy(sbuf
, iv
, blocklen
); 
 810                 /* find the next source block */ 
 811                 while (s 
&& sn 
>= s
->m_len
) { 
 817                 /* skip over empty mbuf */ 
 818                 while (s 
&& s
->m_len 
== 0) 
 822         m_freem(scut
->m_next
); 
 823         scut
->m_len 
= scutoff
; 
 827         bzero(iv
, sizeof(iv
)); 
 828         bzero(sbuf
, sizeof(sbuf
)); 
 834 esp_cbc_encrypt(m
, off
, plen
, sav
, algo
, ivlen
) 
 838         struct secasvar 
*sav
; 
 839         const struct esp_algorithm 
*algo
; 
 843         struct mbuf 
*d
, *d0
, *dp
; 
 844         int soff
, doff
; /*offset from the head of chain, to head of this mbuf */ 
 845         int sn
, dn
;     /*offset from the head of the mbuf, to meat */ 
 846         size_t ivoff
, bodyoff
; 
 847         u_int8_t iv
[MAXIVLEN
], *ivp
; 
 848         u_int8_t sbuf
[MAXIVLEN
], *sp
; 
 856         if (ivlen 
!= sav
->ivlen 
|| ivlen 
> sizeof(iv
)) { 
 857                 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: " 
 858                     "unsupported ivlen %d\n", algo
->name
, ivlen
)); 
 863         /* assumes blocklen == padbound */ 
 864         blocklen 
= algo
->padbound
; 
 867         if (blocklen 
> sizeof(iv
)) { 
 868                 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: " 
 869                     "unsupported blocklen %d\n", algo
->name
, blocklen
)); 
 875         if (sav
->flags 
& SADB_X_EXT_OLD
) { 
 877                 ivoff 
= off 
+ sizeof(struct esp
); 
 878                 bodyoff 
= off 
+ sizeof(struct esp
) + ivlen
; 
 882                 if (sav
->flags 
& SADB_X_EXT_DERIV
) { 
 884                          * draft-ietf-ipsec-ciph-des-derived-00.txt 
 885                          * uses sequence number field as IV field. 
 887                         ivoff 
= off 
+ sizeof(struct esp
); 
 888                         bodyoff 
= off 
+ sizeof(struct esp
) + sizeof(u_int32_t
); 
 889                         ivlen 
= sizeof(u_int32_t
); 
 892                         ivoff 
= off 
+ sizeof(struct newesp
); 
 893                         bodyoff 
= off 
+ sizeof(struct newesp
) + ivlen
; 
 898         /* put iv into the packet.  if we are in derived mode, use seqno. */ 
 900                 m_copydata(m
, ivoff
, ivlen
, iv
); 
 902                 bcopy(sav
->iv
, iv
, ivlen
); 
 903                 /* maybe it is better to overwrite dest, not source */ 
 904                 m_copyback(m
, ivoff
, ivlen
, iv
); 
 908         if (ivlen 
== blocklen
) 
 910         else if (ivlen 
== 4 && blocklen 
== 8) { 
 911                 bcopy(&iv
[0], &iv
[4], 4); 
 917                 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: " 
 918                     "unsupported ivlen/blocklen: %d %d\n", 
 919                     algo
->name
, ivlen
, blocklen
)); 
 924         if (m
->m_pkthdr
.len 
< bodyoff
) { 
 925                 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: bad len %d/%lu\n", 
 926                     algo
->name
, m
->m_pkthdr
.len
, (unsigned long)bodyoff
)); 
 930         if ((m
->m_pkthdr
.len 
- bodyoff
) % blocklen
) { 
 931                 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: " 
 932                     "payload length must be multiple of %lu\n", 
 933                     algo
->name
, (unsigned long)algo
->padbound
)); 
 940         soff 
= doff 
= sn 
= dn 
= 0; 
 944         while (soff 
< bodyoff
) { 
 945                 if (soff 
+ s
->m_len 
> bodyoff
) { 
 956         /* skip over empty mbuf */ 
 957         while (s 
&& s
->m_len 
== 0) 
 960         while (soff 
< m
->m_pkthdr
.len
) { 
 962                 if (sn 
+ blocklen 
<= s
->m_len
) { 
 963                         /* body is continuous */ 
 964                         sp 
= mtod(s
, u_int8_t 
*) + sn
; 
 966                         /* body is non-continuous */ 
 967                         m_copydata(s
, sn
, blocklen
, sbuf
); 
 972                 if (!d 
|| dn 
+ blocklen 
> d
->m_len
) { 
 975                         MGET(d
, M_DONTWAIT
, MT_DATA
); 
 976                         i 
= m
->m_pkthdr
.len 
- (soff 
+ sn
); 
 978                                 MCLGET(d
, M_DONTWAIT
); 
 979                                 if ((d
->m_flags 
& M_EXT
) == 0) { 
 995                         d
->m_len 
= (M_TRAILINGSPACE(d
) / blocklen
) * blocklen
; 
1004                 for (i 
= 0; i 
< blocklen
; i
++) 
1008                 (*algo
->blockencrypt
)(algo
, sav
, sp
, mtod(d
, u_int8_t 
*) + dn
); 
1011                 ivp 
= mtod(d
, u_int8_t 
*) + dn
; 
1016                 /* find the next source block */ 
1017                 while (s 
&& sn 
>= s
->m_len
) { 
1023                 /* skip over empty mbuf */ 
1024                 while (s 
&& s
->m_len 
== 0) 
1028         m_freem(scut
->m_next
); 
1029         scut
->m_len 
= scutoff
; 
1033         bzero(iv
, sizeof(iv
)); 
1034         bzero(sbuf
, sizeof(sbuf
)); 
1036         key_sa_stir_iv(sav
); 
1041 /*------------------------------------------------------------*/ 
1043 /* does not free m0 on error */ 
1045 esp_auth(m0
, skip
, length
, sav
, sum
) 
1047         size_t skip
;    /* offset to ESP header */ 
1048         size_t length
;  /* payload length */ 
1049         struct secasvar 
*sav
; 
1054         struct ah_algorithm_state s
; 
1055         u_char sumbuf
[AH_MAXSUMSIZE
]; 
1056         const struct ah_algorithm 
*algo
; 
1061         if (m0
->m_pkthdr
.len 
< skip
) { 
1062                 ipseclog((LOG_DEBUG
, "esp_auth: mbuf length < skip\n")); 
1065         if (m0
->m_pkthdr
.len 
< skip 
+ length
) { 
1066                 ipseclog((LOG_DEBUG
, 
1067                     "esp_auth: mbuf length < skip + length\n")); 
1071          * length of esp part (excluding authentication data) must be 4n, 
1072          * since nexthdr must be at offset 4n+3. 
1075                 ipseclog((LOG_ERR
, "esp_auth: length is not multiple of 4\n")); 
1079                 ipseclog((LOG_DEBUG
, "esp_auth: NULL SA passed\n")); 
1082         algo 
= ah_algorithm_lookup(sav
->alg_auth
); 
1085                     "esp_auth: bad ESP auth algorithm passed: %d\n", 
1093         siz 
= (((*algo
->sumsiz
)(sav
) + 3) & ~(4 - 1)); 
1094         if (sizeof(sumbuf
) < siz
) { 
1095                 ipseclog((LOG_DEBUG
, 
1096                     "esp_auth: AH_MAXSUMSIZE is too small: siz=%lu\n", 
1101         /* skip the header */ 
1104                         panic("mbuf chain?"); 
1105                 if (m
->m_len 
<= skip
) { 
1115         error 
= (*algo
->init
)(&s
, sav
); 
1119         while (0 < length
) { 
1121                         panic("mbuf chain?"); 
1123                 if (m
->m_len 
- off 
< length
) { 
1124                         (*algo
->update
)(&s
, mtod(m
, u_char 
*) + off
, 
1126                         length 
-= m
->m_len 
- off
; 
1130                         (*algo
->update
)(&s
, mtod(m
, u_char 
*) + off
, length
); 
1134         (*algo
->result
)(&s
, sumbuf
); 
1135         bcopy(sumbuf
, sum
, siz
);        /*XXX*/