1 /* 2 * xfrm algorithm interface 3 * 4 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the Free 8 * Software Foundation; either version 2 of the License, or (at your option) 9 * any later version. 10 */ 11 12 #include <linux/module.h> 13 #include <linux/kernel.h> 14 #include <linux/pfkeyv2.h> 15 #include <linux/crypto.h> 16 #include <net/xfrm.h> 17 #if defined(CONFIG_INET_AH) || defined(CONFIG_INET_AH_MODULE) || defined(CONFIG_INET6_AH) || defined(CONFIG_INET6_AH_MODULE) 18 #include <net/ah.h> 19 #endif 20 #if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE) 21 #include <net/esp.h> 22 #endif 23 #include <asm/scatterlist.h> 24 25 /* 26 * Algorithms supported by IPsec. These entries contain properties which 27 * are used in key negotiation and xfrm processing, and are used to verify 28 * that instantiated crypto transforms have correct parameters for IPsec 29 * purposes. 30 */ 31 static struct xfrm_algo_desc aalg_list[] = { 32 { 33 .name = "hmac(digest_null)", 34 .compat = "digest_null", 35 36 .uinfo = { 37 .auth = { 38 .icv_truncbits = 0, 39 .icv_fullbits = 0, 40 } 41 }, 42 43 .desc = { 44 .sadb_alg_id = SADB_X_AALG_NULL, 45 .sadb_alg_ivlen = 0, 46 .sadb_alg_minbits = 0, 47 .sadb_alg_maxbits = 0 48 } 49 }, 50 { 51 .name = "hmac(md5)", 52 .compat = "md5", 53 54 .uinfo = { 55 .auth = { 56 .icv_truncbits = 96, 57 .icv_fullbits = 128, 58 } 59 }, 60 61 .desc = { 62 .sadb_alg_id = SADB_AALG_MD5HMAC, 63 .sadb_alg_ivlen = 0, 64 .sadb_alg_minbits = 128, 65 .sadb_alg_maxbits = 128 66 } 67 }, 68 { 69 .name = "hmac(sha1)", 70 .compat = "sha1", 71 72 .uinfo = { 73 .auth = { 74 .icv_truncbits = 96, 75 .icv_fullbits = 160, 76 } 77 }, 78 79 .desc = { 80 .sadb_alg_id = SADB_AALG_SHA1HMAC, 81 .sadb_alg_ivlen = 0, 82 .sadb_alg_minbits = 160, 83 .sadb_alg_maxbits = 160 84 } 85 }, 86 { 87 .name = "hmac(sha256)", 88 .compat = "sha256", 89 90 .uinfo = { 91 .auth = { 92 .icv_truncbits = 96, 93 .icv_fullbits = 256, 94 } 95 }, 96 97 .desc = { 98 .sadb_alg_id = SADB_X_AALG_SHA2_256HMAC, 99 .sadb_alg_ivlen = 0, 100 .sadb_alg_minbits = 256, 101 .sadb_alg_maxbits = 256 102 } 103 }, 104 { 105 .name = "hmac(ripemd160)", 106 .compat = "ripemd160", 107 108 .uinfo = { 109 .auth = { 110 .icv_truncbits = 96, 111 .icv_fullbits = 160, 112 } 113 }, 114 115 .desc = { 116 .sadb_alg_id = SADB_X_AALG_RIPEMD160HMAC, 117 .sadb_alg_ivlen = 0, 118 .sadb_alg_minbits = 160, 119 .sadb_alg_maxbits = 160 120 } 121 }, 122 { 123 .name = "xcbc(aes)", 124 125 .uinfo = { 126 .auth = { 127 .icv_truncbits = 96, 128 .icv_fullbits = 128, 129 } 130 }, 131 132 .desc = { 133 .sadb_alg_id = SADB_X_AALG_AES_XCBC_MAC, 134 .sadb_alg_ivlen = 0, 135 .sadb_alg_minbits = 128, 136 .sadb_alg_maxbits = 128 137 } 138 }, 139 }; 140 141 static struct xfrm_algo_desc ealg_list[] = { 142 { 143 .name = "ecb(cipher_null)", 144 .compat = "cipher_null", 145 146 .uinfo = { 147 .encr = { 148 .blockbits = 8, 149 .defkeybits = 0, 150 } 151 }, 152 153 .desc = { 154 .sadb_alg_id = SADB_EALG_NULL, 155 .sadb_alg_ivlen = 0, 156 .sadb_alg_minbits = 0, 157 .sadb_alg_maxbits = 0 158 } 159 }, 160 { 161 .name = "cbc(des)", 162 .compat = "des", 163 164 .uinfo = { 165 .encr = { 166 .blockbits = 64, 167 .defkeybits = 64, 168 } 169 }, 170 171 .desc = { 172 .sadb_alg_id = SADB_EALG_DESCBC, 173 .sadb_alg_ivlen = 8, 174 .sadb_alg_minbits = 64, 175 .sadb_alg_maxbits = 64 176 } 177 }, 178 { 179 .name = "cbc(des3_ede)", 180 .compat = "des3_ede", 181 182 .uinfo = { 183 .encr = { 184 .blockbits = 64, 185 .defkeybits = 192, 186 } 187 }, 188 189 .desc = { 190 .sadb_alg_id = SADB_EALG_3DESCBC, 191 .sadb_alg_ivlen = 8, 192 .sadb_alg_minbits = 192, 193 .sadb_alg_maxbits = 192 194 } 195 }, 196 { 197 .name = "cbc(cast128)", 198 .compat = "cast128", 199 200 .uinfo = { 201 .encr = { 202 .blockbits = 64, 203 .defkeybits = 128, 204 } 205 }, 206 207 .desc = { 208 .sadb_alg_id = SADB_X_EALG_CASTCBC, 209 .sadb_alg_ivlen = 8, 210 .sadb_alg_minbits = 40, 211 .sadb_alg_maxbits = 128 212 } 213 }, 214 { 215 .name = "cbc(blowfish)", 216 .compat = "blowfish", 217 218 .uinfo = { 219 .encr = { 220 .blockbits = 64, 221 .defkeybits = 128, 222 } 223 }, 224 225 .desc = { 226 .sadb_alg_id = SADB_X_EALG_BLOWFISHCBC, 227 .sadb_alg_ivlen = 8, 228 .sadb_alg_minbits = 40, 229 .sadb_alg_maxbits = 448 230 } 231 }, 232 { 233 .name = "cbc(aes)", 234 .compat = "aes", 235 236 .uinfo = { 237 .encr = { 238 .blockbits = 128, 239 .defkeybits = 128, 240 } 241 }, 242 243 .desc = { 244 .sadb_alg_id = SADB_X_EALG_AESCBC, 245 .sadb_alg_ivlen = 8, 246 .sadb_alg_minbits = 128, 247 .sadb_alg_maxbits = 256 248 } 249 }, 250 { 251 .name = "cbc(serpent)", 252 .compat = "serpent", 253 254 .uinfo = { 255 .encr = { 256 .blockbits = 128, 257 .defkeybits = 128, 258 } 259 }, 260 261 .desc = { 262 .sadb_alg_id = SADB_X_EALG_SERPENTCBC, 263 .sadb_alg_ivlen = 8, 264 .sadb_alg_minbits = 128, 265 .sadb_alg_maxbits = 256, 266 } 267 }, 268 { 269 .name = "cbc(camellia)", 270 271 .uinfo = { 272 .encr = { 273 .blockbits = 128, 274 .defkeybits = 128, 275 } 276 }, 277 278 .desc = { 279 .sadb_alg_id = SADB_X_EALG_CAMELLIACBC, 280 .sadb_alg_ivlen = 8, 281 .sadb_alg_minbits = 128, 282 .sadb_alg_maxbits = 256 283 } 284 }, 285 { 286 .name = "cbc(twofish)", 287 .compat = "twofish", 288 289 .uinfo = { 290 .encr = { 291 .blockbits = 128, 292 .defkeybits = 128, 293 } 294 }, 295 296 .desc = { 297 .sadb_alg_id = SADB_X_EALG_TWOFISHCBC, 298 .sadb_alg_ivlen = 8, 299 .sadb_alg_minbits = 128, 300 .sadb_alg_maxbits = 256 301 } 302 }, 303 }; 304 305 static struct xfrm_algo_desc calg_list[] = { 306 { 307 .name = "deflate", 308 .uinfo = { 309 .comp = { 310 .threshold = 90, 311 } 312 }, 313 .desc = { .sadb_alg_id = SADB_X_CALG_DEFLATE } 314 }, 315 { 316 .name = "lzs", 317 .uinfo = { 318 .comp = { 319 .threshold = 90, 320 } 321 }, 322 .desc = { .sadb_alg_id = SADB_X_CALG_LZS } 323 }, 324 { 325 .name = "lzjh", 326 .uinfo = { 327 .comp = { 328 .threshold = 50, 329 } 330 }, 331 .desc = { .sadb_alg_id = SADB_X_CALG_LZJH } 332 }, 333 }; 334 335 static inline int aalg_entries(void) 336 { 337 return ARRAY_SIZE(aalg_list); 338 } 339 340 static inline int ealg_entries(void) 341 { 342 return ARRAY_SIZE(ealg_list); 343 } 344 345 static inline int calg_entries(void) 346 { 347 return ARRAY_SIZE(calg_list); 348 } 349 350 struct xfrm_algo_list { 351 struct xfrm_algo_desc *algs; 352 int entries; 353 u32 type; 354 u32 mask; 355 }; 356 357 static const struct xfrm_algo_list xfrm_aalg_list = { 358 .algs = aalg_list, 359 .entries = ARRAY_SIZE(aalg_list), 360 .type = CRYPTO_ALG_TYPE_HASH, 361 .mask = CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC, 362 }; 363 364 static const struct xfrm_algo_list xfrm_ealg_list = { 365 .algs = ealg_list, 366 .entries = ARRAY_SIZE(ealg_list), 367 .type = CRYPTO_ALG_TYPE_BLKCIPHER, 368 .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC, 369 }; 370 371 static const struct xfrm_algo_list xfrm_calg_list = { 372 .algs = calg_list, 373 .entries = ARRAY_SIZE(calg_list), 374 .type = CRYPTO_ALG_TYPE_COMPRESS, 375 .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC, 376 }; 377 378 static struct xfrm_algo_desc *xfrm_find_algo( 379 const struct xfrm_algo_list *algo_list, 380 int match(const struct xfrm_algo_desc *entry, const void *data), 381 const void *data, int probe) 382 { 383 struct xfrm_algo_desc *list = algo_list->algs; 384 int i, status; 385 386 for (i = 0; i < algo_list->entries; i++) { 387 if (!match(list + i, data)) 388 continue; 389 390 if (list[i].available) 391 return &list[i]; 392 393 if (!probe) 394 break; 395 396 status = crypto_has_alg(list[i].name, algo_list->type, 397 algo_list->mask); 398 if (!status) 399 break; 400 401 list[i].available = status; 402 return &list[i]; 403 } 404 return NULL; 405 } 406 407 static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry, 408 const void *data) 409 { 410 return entry->desc.sadb_alg_id == (unsigned long)data; 411 } 412 413 struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id) 414 { 415 return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match, 416 (void *)(unsigned long)alg_id, 1); 417 } 418 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid); 419 420 struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id) 421 { 422 return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match, 423 (void *)(unsigned long)alg_id, 1); 424 } 425 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid); 426 427 struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id) 428 { 429 return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match, 430 (void *)(unsigned long)alg_id, 1); 431 } 432 EXPORT_SYMBOL_GPL(xfrm_calg_get_byid); 433 434 static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry, 435 const void *data) 436 { 437 const char *name = data; 438 439 return name && (!strcmp(name, entry->name) || 440 (entry->compat && !strcmp(name, entry->compat))); 441 } 442 443 struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe) 444 { 445 return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name, 446 probe); 447 } 448 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname); 449 450 struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe) 451 { 452 return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name, 453 probe); 454 } 455 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname); 456 457 struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe) 458 { 459 return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name, 460 probe); 461 } 462 EXPORT_SYMBOL_GPL(xfrm_calg_get_byname); 463 464 struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx) 465 { 466 if (idx >= aalg_entries()) 467 return NULL; 468 469 return &aalg_list[idx]; 470 } 471 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx); 472 473 struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx) 474 { 475 if (idx >= ealg_entries()) 476 return NULL; 477 478 return &ealg_list[idx]; 479 } 480 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx); 481 482 /* 483 * Probe for the availability of crypto algorithms, and set the available 484 * flag for any algorithms found on the system. This is typically called by 485 * pfkey during userspace SA add, update or register. 486 */ 487 void xfrm_probe_algs(void) 488 { 489 #ifdef CONFIG_CRYPTO 490 int i, status; 491 492 BUG_ON(in_softirq()); 493 494 for (i = 0; i < aalg_entries(); i++) { 495 status = crypto_has_hash(aalg_list[i].name, 0, 496 CRYPTO_ALG_ASYNC); 497 if (aalg_list[i].available != status) 498 aalg_list[i].available = status; 499 } 500 501 for (i = 0; i < ealg_entries(); i++) { 502 status = crypto_has_blkcipher(ealg_list[i].name, 0, 503 CRYPTO_ALG_ASYNC); 504 if (ealg_list[i].available != status) 505 ealg_list[i].available = status; 506 } 507 508 for (i = 0; i < calg_entries(); i++) { 509 status = crypto_has_comp(calg_list[i].name, 0, 510 CRYPTO_ALG_ASYNC); 511 if (calg_list[i].available != status) 512 calg_list[i].available = status; 513 } 514 #endif 515 } 516 EXPORT_SYMBOL_GPL(xfrm_probe_algs); 517 518 int xfrm_count_auth_supported(void) 519 { 520 int i, n; 521 522 for (i = 0, n = 0; i < aalg_entries(); i++) 523 if (aalg_list[i].available) 524 n++; 525 return n; 526 } 527 EXPORT_SYMBOL_GPL(xfrm_count_auth_supported); 528 529 int xfrm_count_enc_supported(void) 530 { 531 int i, n; 532 533 for (i = 0, n = 0; i < ealg_entries(); i++) 534 if (ealg_list[i].available) 535 n++; 536 return n; 537 } 538 EXPORT_SYMBOL_GPL(xfrm_count_enc_supported); 539 540 /* Move to common area: it is shared with AH. */ 541 542 int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc, 543 int offset, int len, icv_update_fn_t icv_update) 544 { 545 int start = skb_headlen(skb); 546 int i, copy = start - offset; 547 int err; 548 struct scatterlist sg; 549 550 /* Checksum header. */ 551 if (copy > 0) { 552 if (copy > len) 553 copy = len; 554 555 sg.page = virt_to_page(skb->data + offset); 556 sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE; 557 sg.length = copy; 558 559 err = icv_update(desc, &sg, copy); 560 if (unlikely(err)) 561 return err; 562 563 if ((len -= copy) == 0) 564 return 0; 565 offset += copy; 566 } 567 568 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 569 int end; 570 571 BUG_TRAP(start <= offset + len); 572 573 end = start + skb_shinfo(skb)->frags[i].size; 574 if ((copy = end - offset) > 0) { 575 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 576 577 if (copy > len) 578 copy = len; 579 580 sg.page = frag->page; 581 sg.offset = frag->page_offset + offset-start; 582 sg.length = copy; 583 584 err = icv_update(desc, &sg, copy); 585 if (unlikely(err)) 586 return err; 587 588 if (!(len -= copy)) 589 return 0; 590 offset += copy; 591 } 592 start = end; 593 } 594 595 if (skb_shinfo(skb)->frag_list) { 596 struct sk_buff *list = skb_shinfo(skb)->frag_list; 597 598 for (; list; list = list->next) { 599 int end; 600 601 BUG_TRAP(start <= offset + len); 602 603 end = start + list->len; 604 if ((copy = end - offset) > 0) { 605 if (copy > len) 606 copy = len; 607 err = skb_icv_walk(list, desc, offset-start, 608 copy, icv_update); 609 if (unlikely(err)) 610 return err; 611 if ((len -= copy) == 0) 612 return 0; 613 offset += copy; 614 } 615 start = end; 616 } 617 } 618 BUG_ON(len); 619 return 0; 620 } 621 EXPORT_SYMBOL_GPL(skb_icv_walk); 622 623 #if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE) 624 625 void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len) 626 { 627 if (tail != skb) { 628 skb->data_len += len; 629 skb->len += len; 630 } 631 return skb_put(tail, len); 632 } 633 EXPORT_SYMBOL_GPL(pskb_put); 634 #endif 635