1 /* 2 * Crypto wrapper for Linux kernel AF_ALG 3 * Copyright (c) 2017, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "includes.h" 10 #include <linux/if_alg.h> 11 12 #include "common.h" 13 #include "crypto.h" 14 #include "md5.h" 15 #include "sha1.h" 16 #include "sha256.h" 17 #include "sha384.h" 18 #include "aes.h" 19 20 21 #ifndef SOL_ALG 22 #define SOL_ALG 279 23 #endif /* SOL_ALG */ 24 25 26 static int linux_af_alg_socket(const char *type, const char *name) 27 { 28 struct sockaddr_alg sa; 29 int s; 30 31 if (TEST_FAIL()) 32 return -1; 33 34 s = socket(AF_ALG, SOCK_SEQPACKET, 0); 35 if (s < 0) { 36 wpa_printf(MSG_ERROR, "%s: Failed to open AF_ALG socket: %s", 37 __func__, strerror(errno)); 38 return -1; 39 } 40 41 os_memset(&sa, 0, sizeof(sa)); 42 sa.salg_family = AF_ALG; 43 os_strlcpy((char *) sa.salg_type, type, sizeof(sa.salg_type)); 44 os_strlcpy((char *) sa.salg_name, name, sizeof(sa.salg_type)); 45 if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) { 46 wpa_printf(MSG_ERROR, 47 "%s: Failed to bind AF_ALG socket(%s,%s): %s", 48 __func__, type, name, strerror(errno)); 49 close(s); 50 return -1; 51 } 52 53 return s; 54 } 55 56 57 static int linux_af_alg_hash_vector(const char *alg, const u8 *key, 58 size_t key_len, size_t num_elem, 59 const u8 *addr[], const size_t *len, 60 u8 *mac, size_t mac_len) 61 { 62 int s, t; 63 size_t i; 64 ssize_t res; 65 int ret = -1; 66 67 s = linux_af_alg_socket("hash", alg); 68 if (s < 0) 69 return -1; 70 71 if (key && setsockopt(s, SOL_ALG, ALG_SET_KEY, key, key_len) < 0) { 72 wpa_printf(MSG_ERROR, "%s: setsockopt(ALG_SET_KEY) failed: %s", 73 __func__, strerror(errno)); 74 close(s); 75 return -1; 76 } 77 78 t = accept(s, NULL, NULL); 79 if (t < 0) { 80 wpa_printf(MSG_ERROR, "%s: accept on AF_ALG socket failed: %s", 81 __func__, strerror(errno)); 82 close(s); 83 return -1; 84 } 85 86 for (i = 0; i < num_elem; i++) { 87 res = send(t, addr[i], len[i], i + 1 < num_elem ? MSG_MORE : 0); 88 if (res < 0) { 89 wpa_printf(MSG_ERROR, 90 "%s: send on AF_ALG socket failed: %s", 91 __func__, strerror(errno)); 92 goto fail; 93 } 94 if ((size_t) res < len[i]) { 95 wpa_printf(MSG_ERROR, 96 "%s: send on AF_ALG socket did not accept full buffer (%d/%d)", 97 __func__, (int) res, (int) len[i]); 98 goto fail; 99 } 100 } 101 102 res = recv(t, mac, mac_len, 0); 103 if (res < 0) { 104 wpa_printf(MSG_ERROR, 105 "%s: recv on AF_ALG socket failed: %s", 106 __func__, strerror(errno)); 107 goto fail; 108 } 109 if ((size_t) res < mac_len) { 110 wpa_printf(MSG_ERROR, 111 "%s: recv on AF_ALG socket did not return full buffer (%d/%d)", 112 __func__, (int) res, (int) mac_len); 113 goto fail; 114 } 115 116 ret = 0; 117 fail: 118 close(t); 119 close(s); 120 121 return ret; 122 } 123 124 125 int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 126 { 127 return linux_af_alg_hash_vector("md4", NULL, 0, num_elem, addr, len, 128 mac, 16); 129 } 130 131 132 int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 133 { 134 return linux_af_alg_hash_vector("md5", NULL, 0, num_elem, addr, len, 135 mac, MD5_MAC_LEN); 136 } 137 138 139 int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, 140 u8 *mac) 141 { 142 return linux_af_alg_hash_vector("sha1", NULL, 0, num_elem, addr, len, 143 mac, SHA1_MAC_LEN); 144 } 145 146 147 int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, 148 u8 *mac) 149 { 150 return linux_af_alg_hash_vector("sha256", NULL, 0, num_elem, addr, len, 151 mac, SHA256_MAC_LEN); 152 } 153 154 155 int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, 156 u8 *mac) 157 { 158 return linux_af_alg_hash_vector("sha384", NULL, 0, num_elem, addr, len, 159 mac, SHA384_MAC_LEN); 160 } 161 162 163 int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, 164 u8 *mac) 165 { 166 return linux_af_alg_hash_vector("sha512", NULL, 0, num_elem, addr, len, 167 mac, 64); 168 } 169 170 171 int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, 172 const u8 *addr[], const size_t *len, u8 *mac) 173 { 174 return linux_af_alg_hash_vector("hmac(md5)", key, key_len, num_elem, 175 addr, len, mac, 16); 176 } 177 178 179 int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, 180 u8 *mac) 181 { 182 return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac); 183 } 184 185 186 int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, 187 const u8 *addr[], const size_t *len, u8 *mac) 188 { 189 return linux_af_alg_hash_vector("hmac(sha1)", key, key_len, num_elem, 190 addr, len, mac, SHA1_MAC_LEN); 191 } 192 193 194 int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, 195 u8 *mac) 196 { 197 return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac); 198 } 199 200 201 int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, 202 const u8 *addr[], const size_t *len, u8 *mac) 203 { 204 return linux_af_alg_hash_vector("hmac(sha256)", key, key_len, num_elem, 205 addr, len, mac, SHA256_MAC_LEN); 206 } 207 208 209 int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, 210 size_t data_len, u8 *mac) 211 { 212 return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac); 213 } 214 215 216 int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem, 217 const u8 *addr[], const size_t *len, u8 *mac) 218 { 219 return linux_af_alg_hash_vector("hmac(sha384)", key, key_len, num_elem, 220 addr, len, mac, SHA384_MAC_LEN); 221 } 222 223 224 int hmac_sha384(const u8 *key, size_t key_len, const u8 *data, 225 size_t data_len, u8 *mac) 226 { 227 return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac); 228 } 229 230 231 struct crypto_hash { 232 int s; 233 int t; 234 size_t mac_len; 235 int failed; 236 }; 237 238 239 struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, 240 size_t key_len) 241 { 242 struct crypto_hash *ctx; 243 const char *name; 244 245 ctx = os_zalloc(sizeof(*ctx)); 246 if (!ctx) 247 return NULL; 248 249 switch (alg) { 250 case CRYPTO_HASH_ALG_MD5: 251 name = "md5"; 252 ctx->mac_len = MD5_MAC_LEN; 253 break; 254 case CRYPTO_HASH_ALG_SHA1: 255 name = "sha1"; 256 ctx->mac_len = SHA1_MAC_LEN; 257 break; 258 case CRYPTO_HASH_ALG_HMAC_MD5: 259 name = "hmac(md5)"; 260 ctx->mac_len = MD5_MAC_LEN; 261 break; 262 case CRYPTO_HASH_ALG_HMAC_SHA1: 263 name = "hmac(sha1)"; 264 ctx->mac_len = SHA1_MAC_LEN; 265 break; 266 case CRYPTO_HASH_ALG_SHA256: 267 name = "sha256"; 268 ctx->mac_len = SHA256_MAC_LEN; 269 break; 270 case CRYPTO_HASH_ALG_HMAC_SHA256: 271 name = "hmac(sha256)"; 272 ctx->mac_len = SHA256_MAC_LEN; 273 break; 274 case CRYPTO_HASH_ALG_SHA384: 275 name = "sha384"; 276 ctx->mac_len = SHA384_MAC_LEN; 277 break; 278 case CRYPTO_HASH_ALG_SHA512: 279 name = "sha512"; 280 ctx->mac_len = 64; 281 break; 282 default: 283 os_free(ctx); 284 return NULL; 285 } 286 287 ctx->s = linux_af_alg_socket("hash", name); 288 if (ctx->s < 0) { 289 os_free(ctx); 290 return NULL; 291 } 292 293 if (key && key_len && 294 setsockopt(ctx->s, SOL_ALG, ALG_SET_KEY, key, key_len) < 0) { 295 wpa_printf(MSG_ERROR, "%s: setsockopt(ALG_SET_KEY) failed: %s", 296 __func__, strerror(errno)); 297 close(ctx->s); 298 os_free(ctx); 299 return NULL; 300 } 301 302 ctx->t = accept(ctx->s, NULL, NULL); 303 if (ctx->t < 0) { 304 wpa_printf(MSG_ERROR, "%s: accept on AF_ALG socket failed: %s", 305 __func__, strerror(errno)); 306 close(ctx->s); 307 os_free(ctx); 308 return NULL; 309 } 310 311 return ctx; 312 } 313 314 315 void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) 316 { 317 ssize_t res; 318 319 if (!ctx) 320 return; 321 322 res = send(ctx->t, data, len, MSG_MORE); 323 if (res < 0) { 324 wpa_printf(MSG_ERROR, 325 "%s: send on AF_ALG socket failed: %s", 326 __func__, strerror(errno)); 327 ctx->failed = 1; 328 return; 329 } 330 if ((size_t) res < len) { 331 wpa_printf(MSG_ERROR, 332 "%s: send on AF_ALG socket did not accept full buffer (%d/%d)", 333 __func__, (int) res, (int) len); 334 ctx->failed = 1; 335 return; 336 } 337 } 338 339 340 static void crypto_hash_deinit(struct crypto_hash *ctx) 341 { 342 close(ctx->s); 343 close(ctx->t); 344 os_free(ctx); 345 } 346 347 348 int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) 349 { 350 ssize_t res; 351 352 if (!ctx) 353 return -2; 354 355 if (!mac || !len) { 356 crypto_hash_deinit(ctx); 357 return 0; 358 } 359 360 if (ctx->failed) { 361 crypto_hash_deinit(ctx); 362 return -2; 363 } 364 365 if (*len < ctx->mac_len) { 366 crypto_hash_deinit(ctx); 367 *len = ctx->mac_len; 368 return -1; 369 } 370 *len = ctx->mac_len; 371 372 res = recv(ctx->t, mac, ctx->mac_len, 0); 373 if (res < 0) { 374 wpa_printf(MSG_ERROR, 375 "%s: recv on AF_ALG socket failed: %s", 376 __func__, strerror(errno)); 377 crypto_hash_deinit(ctx); 378 return -2; 379 } 380 if ((size_t) res < ctx->mac_len) { 381 wpa_printf(MSG_ERROR, 382 "%s: recv on AF_ALG socket did not return full buffer (%d/%d)", 383 __func__, (int) res, (int) ctx->mac_len); 384 crypto_hash_deinit(ctx); 385 return -2; 386 } 387 388 crypto_hash_deinit(ctx); 389 return 0; 390 } 391 392 393 struct linux_af_alg_skcipher { 394 int s; 395 int t; 396 }; 397 398 399 static void linux_af_alg_skcipher_deinit(struct linux_af_alg_skcipher *skcipher) 400 { 401 if (!skcipher) 402 return; 403 if (skcipher->s >= 0) 404 close(skcipher->s); 405 if (skcipher->t >= 0) 406 close(skcipher->t); 407 os_free(skcipher); 408 } 409 410 411 static struct linux_af_alg_skcipher * 412 linux_af_alg_skcipher(const char *alg, const u8 *key, size_t key_len) 413 { 414 struct linux_af_alg_skcipher *skcipher; 415 416 skcipher = os_zalloc(sizeof(*skcipher)); 417 if (!skcipher) 418 goto fail; 419 skcipher->t = -1; 420 421 skcipher->s = linux_af_alg_socket("skcipher", alg); 422 if (skcipher->s < 0) 423 goto fail; 424 425 if (setsockopt(skcipher->s, SOL_ALG, ALG_SET_KEY, key, key_len) < 0) { 426 wpa_printf(MSG_ERROR, "%s: setsockopt(ALG_SET_KEY) failed: %s", 427 __func__, strerror(errno)); 428 goto fail; 429 } 430 431 skcipher->t = accept(skcipher->s, NULL, NULL); 432 if (skcipher->t < 0) { 433 wpa_printf(MSG_ERROR, "%s: accept on AF_ALG socket failed: %s", 434 __func__, strerror(errno)); 435 goto fail; 436 } 437 438 return skcipher; 439 fail: 440 linux_af_alg_skcipher_deinit(skcipher); 441 return NULL; 442 } 443 444 445 static int linux_af_alg_skcipher_oper(struct linux_af_alg_skcipher *skcipher, 446 int enc, const u8 *in, u8 *out) 447 { 448 char buf[CMSG_SPACE(sizeof(u32))]; 449 struct iovec io[1]; 450 struct msghdr msg; 451 struct cmsghdr *hdr; 452 ssize_t ret; 453 u32 *op; 454 455 io[0].iov_base = (void *) in; 456 io[0].iov_len = AES_BLOCK_SIZE; 457 os_memset(&msg, 0, sizeof(msg)); 458 os_memset(buf, 0, sizeof(buf)); 459 msg.msg_control = buf; 460 msg.msg_controllen = CMSG_SPACE(sizeof(u32)); 461 msg.msg_iov = io; 462 msg.msg_iovlen = 1; 463 hdr = CMSG_FIRSTHDR(&msg); 464 hdr->cmsg_level = SOL_ALG; 465 hdr->cmsg_type = ALG_SET_OP; 466 hdr->cmsg_len = CMSG_LEN(sizeof(u32)); 467 op = (u32 *) CMSG_DATA(hdr); 468 *op = enc ? ALG_OP_ENCRYPT : ALG_OP_DECRYPT; 469 470 ret = sendmsg(skcipher->t, &msg, 0); 471 if (ret < 0) { 472 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 473 __func__, strerror(errno)); 474 return -1; 475 } 476 477 ret = read(skcipher->t, out, AES_BLOCK_SIZE); 478 if (ret < 0) { 479 wpa_printf(MSG_ERROR, "%s: read failed: %s", 480 __func__, strerror(errno)); 481 return -1; 482 } 483 if (ret < AES_BLOCK_SIZE) { 484 wpa_printf(MSG_ERROR, 485 "%s: read did not return full data (%d/%d)", 486 __func__, (int) ret, AES_BLOCK_SIZE); 487 return -1; 488 } 489 490 return 0; 491 } 492 493 494 void * aes_encrypt_init(const u8 *key, size_t len) 495 { 496 return linux_af_alg_skcipher("ecb(aes)", key, len); 497 } 498 499 500 int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) 501 { 502 struct linux_af_alg_skcipher *skcipher = ctx; 503 504 return linux_af_alg_skcipher_oper(skcipher, 1, plain, crypt); 505 } 506 507 508 void aes_encrypt_deinit(void *ctx) 509 { 510 linux_af_alg_skcipher_deinit(ctx); 511 } 512 513 514 void * aes_decrypt_init(const u8 *key, size_t len) 515 { 516 return linux_af_alg_skcipher("ecb(aes)", key, len); 517 } 518 519 520 int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) 521 { 522 struct linux_af_alg_skcipher *skcipher = ctx; 523 524 return linux_af_alg_skcipher_oper(skcipher, 0, crypt, plain); 525 } 526 527 528 void aes_decrypt_deinit(void *ctx) 529 { 530 linux_af_alg_skcipher_deinit(ctx); 531 } 532 533 534 int rc4_skip(const u8 *key, size_t keylen, size_t skip, 535 u8 *data, size_t data_len) 536 { 537 struct linux_af_alg_skcipher *skcipher; 538 u8 *skip_buf; 539 char buf[CMSG_SPACE(sizeof(u32))]; 540 struct iovec io[2]; 541 struct msghdr msg; 542 struct cmsghdr *hdr; 543 ssize_t ret; 544 u32 *op; 545 546 skip_buf = os_zalloc(skip + 1); 547 if (!skip_buf) 548 return -1; 549 skcipher = linux_af_alg_skcipher("ecb(arc4)", key, keylen); 550 if (!skcipher) { 551 os_free(skip_buf); 552 return -1; 553 } 554 555 io[0].iov_base = skip_buf; 556 io[0].iov_len = skip; 557 io[1].iov_base = data; 558 io[1].iov_len = data_len; 559 os_memset(&msg, 0, sizeof(msg)); 560 os_memset(buf, 0, sizeof(buf)); 561 msg.msg_control = buf; 562 msg.msg_controllen = CMSG_SPACE(sizeof(u32)); 563 msg.msg_iov = io; 564 msg.msg_iovlen = 2; 565 hdr = CMSG_FIRSTHDR(&msg); 566 hdr->cmsg_level = SOL_ALG; 567 hdr->cmsg_type = ALG_SET_OP; 568 hdr->cmsg_len = CMSG_LEN(sizeof(u32)); 569 op = (u32 *) CMSG_DATA(hdr); 570 *op = ALG_OP_ENCRYPT; 571 572 ret = sendmsg(skcipher->t, &msg, 0); 573 if (ret < 0) { 574 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 575 __func__, strerror(errno)); 576 os_free(skip_buf); 577 linux_af_alg_skcipher_deinit(skcipher); 578 return -1; 579 } 580 os_free(skip_buf); 581 582 msg.msg_control = NULL; 583 msg.msg_controllen = 0; 584 ret = recvmsg(skcipher->t, &msg, 0); 585 if (ret < 0) { 586 wpa_printf(MSG_ERROR, "%s: recvmsg failed: %s", 587 __func__, strerror(errno)); 588 linux_af_alg_skcipher_deinit(skcipher); 589 return -1; 590 } 591 linux_af_alg_skcipher_deinit(skcipher); 592 593 if ((size_t) ret < skip + data_len) { 594 wpa_printf(MSG_ERROR, 595 "%s: recvmsg did not return full data (%d/%d)", 596 __func__, (int) ret, (int) (skip + data_len)); 597 return -1; 598 } 599 600 return 0; 601 } 602 603 604 int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) 605 { 606 u8 pkey[8], next, tmp; 607 int i; 608 struct linux_af_alg_skcipher *skcipher; 609 char buf[CMSG_SPACE(sizeof(u32))]; 610 struct iovec io[1]; 611 struct msghdr msg; 612 struct cmsghdr *hdr; 613 ssize_t ret; 614 u32 *op; 615 int res = -1; 616 617 /* Add parity bits to the key */ 618 next = 0; 619 for (i = 0; i < 7; i++) { 620 tmp = key[i]; 621 pkey[i] = (tmp >> i) | next | 1; 622 next = tmp << (7 - i); 623 } 624 pkey[i] = next | 1; 625 626 skcipher = linux_af_alg_skcipher("ecb(des)", pkey, sizeof(pkey)); 627 if (!skcipher) 628 goto fail; 629 630 io[0].iov_base = (void *) clear; 631 io[0].iov_len = 8; 632 os_memset(&msg, 0, sizeof(msg)); 633 os_memset(buf, 0, sizeof(buf)); 634 msg.msg_control = buf; 635 msg.msg_controllen = CMSG_SPACE(sizeof(u32)); 636 msg.msg_iov = io; 637 msg.msg_iovlen = 1; 638 hdr = CMSG_FIRSTHDR(&msg); 639 hdr->cmsg_level = SOL_ALG; 640 hdr->cmsg_type = ALG_SET_OP; 641 hdr->cmsg_len = CMSG_LEN(sizeof(u32)); 642 op = (u32 *) CMSG_DATA(hdr); 643 *op = ALG_OP_ENCRYPT; 644 645 ret = sendmsg(skcipher->t, &msg, 0); 646 if (ret < 0) { 647 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 648 __func__, strerror(errno)); 649 goto fail; 650 } 651 652 ret = read(skcipher->t, cypher, 8); 653 if (ret < 0) { 654 wpa_printf(MSG_ERROR, "%s: read failed: %s", 655 __func__, strerror(errno)); 656 goto fail; 657 } 658 if (ret < 8) { 659 wpa_printf(MSG_ERROR, 660 "%s: read did not return full data (%d/8)", 661 __func__, (int) ret); 662 goto fail; 663 } 664 665 res = 0; 666 fail: 667 linux_af_alg_skcipher_deinit(skcipher); 668 return res; 669 } 670 671 672 static int aes_128_cbc_oper(const u8 *key, int enc, const u8 *iv, 673 u8 *data, size_t data_len) 674 { 675 struct linux_af_alg_skcipher *skcipher; 676 char buf[100]; 677 struct iovec io[1]; 678 struct msghdr msg; 679 struct cmsghdr *hdr; 680 ssize_t ret; 681 u32 *op; 682 struct af_alg_iv *alg_iv; 683 size_t iv_len = AES_BLOCK_SIZE; 684 685 skcipher = linux_af_alg_skcipher("cbc(aes)", key, 16); 686 if (!skcipher) 687 return -1; 688 689 io[0].iov_base = (void *) data; 690 io[0].iov_len = data_len; 691 os_memset(&msg, 0, sizeof(msg)); 692 os_memset(buf, 0, sizeof(buf)); 693 msg.msg_control = buf; 694 msg.msg_controllen = CMSG_SPACE(sizeof(u32)) + 695 CMSG_SPACE(sizeof(*alg_iv) + iv_len); 696 msg.msg_iov = io; 697 msg.msg_iovlen = 1; 698 699 hdr = CMSG_FIRSTHDR(&msg); 700 hdr->cmsg_level = SOL_ALG; 701 hdr->cmsg_type = ALG_SET_OP; 702 hdr->cmsg_len = CMSG_LEN(sizeof(u32)); 703 op = (u32 *) CMSG_DATA(hdr); 704 *op = enc ? ALG_OP_ENCRYPT : ALG_OP_DECRYPT; 705 706 hdr = CMSG_NXTHDR(&msg, hdr); 707 hdr->cmsg_level = SOL_ALG; 708 hdr->cmsg_type = ALG_SET_IV; 709 hdr->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv_len); 710 alg_iv = (struct af_alg_iv *) CMSG_DATA(hdr); 711 alg_iv->ivlen = iv_len; 712 os_memcpy(alg_iv->iv, iv, iv_len); 713 714 ret = sendmsg(skcipher->t, &msg, 0); 715 if (ret < 0) { 716 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 717 __func__, strerror(errno)); 718 linux_af_alg_skcipher_deinit(skcipher); 719 return -1; 720 } 721 722 ret = recvmsg(skcipher->t, &msg, 0); 723 if (ret < 0) { 724 wpa_printf(MSG_ERROR, "%s: recvmsg failed: %s", 725 __func__, strerror(errno)); 726 linux_af_alg_skcipher_deinit(skcipher); 727 return -1; 728 } 729 if ((size_t) ret < data_len) { 730 wpa_printf(MSG_ERROR, 731 "%s: recvmsg not return full data (%d/%d)", 732 __func__, (int) ret, (int) data_len); 733 linux_af_alg_skcipher_deinit(skcipher); 734 return -1; 735 } 736 737 linux_af_alg_skcipher_deinit(skcipher); 738 return 0; 739 } 740 741 742 int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) 743 { 744 return aes_128_cbc_oper(key, 1, iv, data, data_len); 745 } 746 747 748 int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) 749 { 750 return aes_128_cbc_oper(key, 0, iv, data, data_len); 751 } 752 753 754 int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem, 755 const u8 *addr[], const size_t *len, u8 *mac) 756 { 757 return linux_af_alg_hash_vector("cmac(aes)", key, key_len, num_elem, 758 addr, len, mac, AES_BLOCK_SIZE); 759 } 760 761 762 int omac1_aes_128_vector(const u8 *key, size_t num_elem, 763 const u8 *addr[], const size_t *len, u8 *mac) 764 { 765 return omac1_aes_vector(key, 16, num_elem, addr, len, mac); 766 } 767 768 769 int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac) 770 { 771 return omac1_aes_128_vector(key, 1, &data, &data_len, mac); 772 } 773 774 775 int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac) 776 { 777 return omac1_aes_vector(key, 32, 1, &data, &data_len, mac); 778 } 779 780 781 int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, 782 u8 *plain) 783 { 784 struct linux_af_alg_skcipher *skcipher; 785 char buf[100]; 786 struct iovec io[1]; 787 struct msghdr msg; 788 struct cmsghdr *hdr; 789 ssize_t ret; 790 u32 *op; 791 struct af_alg_iv *alg_iv; 792 size_t iv_len = 8; 793 794 skcipher = linux_af_alg_skcipher("kw(aes)", kek, kek_len); 795 if (!skcipher) 796 return -1; 797 798 io[0].iov_base = (void *) (cipher + iv_len); 799 io[0].iov_len = n * 8; 800 os_memset(&msg, 0, sizeof(msg)); 801 os_memset(buf, 0, sizeof(buf)); 802 msg.msg_control = buf; 803 msg.msg_controllen = CMSG_SPACE(sizeof(u32)) + 804 CMSG_SPACE(sizeof(*alg_iv) + iv_len); 805 msg.msg_iov = io; 806 msg.msg_iovlen = 1; 807 808 hdr = CMSG_FIRSTHDR(&msg); 809 hdr->cmsg_level = SOL_ALG; 810 hdr->cmsg_type = ALG_SET_OP; 811 hdr->cmsg_len = CMSG_LEN(sizeof(u32)); 812 op = (u32 *) CMSG_DATA(hdr); 813 *op = ALG_OP_DECRYPT; 814 815 hdr = CMSG_NXTHDR(&msg, hdr); 816 hdr->cmsg_level = SOL_ALG; 817 hdr->cmsg_type = ALG_SET_IV; 818 hdr->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv_len); 819 alg_iv = (struct af_alg_iv *) CMSG_DATA(hdr); 820 alg_iv->ivlen = iv_len; 821 os_memcpy(alg_iv->iv, cipher, iv_len); 822 823 ret = sendmsg(skcipher->t, &msg, 0); 824 if (ret < 0) { 825 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 826 __func__, strerror(errno)); 827 return -1; 828 } 829 830 ret = read(skcipher->t, plain, n * 8); 831 if (ret < 0) { 832 wpa_printf(MSG_ERROR, "%s: read failed: %s", 833 __func__, strerror(errno)); 834 linux_af_alg_skcipher_deinit(skcipher); 835 return -1; 836 } 837 if (ret < n * 8) { 838 wpa_printf(MSG_ERROR, 839 "%s: read not return full data (%d/%d)", 840 __func__, (int) ret, n * 8); 841 linux_af_alg_skcipher_deinit(skcipher); 842 return -1; 843 } 844 845 linux_af_alg_skcipher_deinit(skcipher); 846 return 0; 847 } 848 849 850 struct crypto_cipher { 851 struct linux_af_alg_skcipher *skcipher; 852 }; 853 854 855 struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, 856 const u8 *iv, const u8 *key, 857 size_t key_len) 858 { 859 struct crypto_cipher *ctx; 860 const char *name; 861 struct af_alg_iv *alg_iv; 862 size_t iv_len = 0; 863 char buf[100]; 864 struct msghdr msg; 865 struct cmsghdr *hdr; 866 ssize_t ret; 867 868 ctx = os_zalloc(sizeof(*ctx)); 869 if (!ctx) 870 return NULL; 871 872 switch (alg) { 873 case CRYPTO_CIPHER_ALG_RC4: 874 name = "ecb(arc4)"; 875 break; 876 case CRYPTO_CIPHER_ALG_AES: 877 name = "cbc(aes)"; 878 iv_len = AES_BLOCK_SIZE; 879 break; 880 case CRYPTO_CIPHER_ALG_3DES: 881 name = "cbc(des3_ede)"; 882 iv_len = 8; 883 break; 884 case CRYPTO_CIPHER_ALG_DES: 885 name = "cbc(des)"; 886 iv_len = 8; 887 break; 888 default: 889 os_free(ctx); 890 return NULL; 891 } 892 893 ctx->skcipher = linux_af_alg_skcipher(name, key, key_len); 894 if (!ctx->skcipher) { 895 os_free(ctx); 896 return NULL; 897 } 898 899 if (iv && iv_len) { 900 os_memset(&msg, 0, sizeof(msg)); 901 os_memset(buf, 0, sizeof(buf)); 902 msg.msg_control = buf; 903 msg.msg_controllen = CMSG_SPACE(sizeof(*alg_iv) + iv_len); 904 hdr = CMSG_FIRSTHDR(&msg); 905 hdr->cmsg_level = SOL_ALG; 906 hdr->cmsg_type = ALG_SET_IV; 907 hdr->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv_len); 908 alg_iv = (struct af_alg_iv *) CMSG_DATA(hdr); 909 alg_iv->ivlen = iv_len; 910 os_memcpy(alg_iv->iv, iv, iv_len); 911 912 ret = sendmsg(ctx->skcipher->t, &msg, 0); 913 if (ret < 0) { 914 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 915 __func__, strerror(errno)); 916 linux_af_alg_skcipher_deinit(ctx->skcipher); 917 os_free(ctx); 918 return NULL; 919 } 920 } 921 922 return ctx; 923 } 924 925 926 static int crypto_cipher_oper(struct crypto_cipher *ctx, u32 type, const u8 *in, 927 u8 *out, size_t len) 928 { 929 char buf[CMSG_SPACE(sizeof(u32))]; 930 struct iovec io[1]; 931 struct msghdr msg; 932 struct cmsghdr *hdr; 933 ssize_t ret; 934 u32 *op; 935 936 io[0].iov_base = (void *) in; 937 io[0].iov_len = len; 938 os_memset(&msg, 0, sizeof(msg)); 939 os_memset(buf, 0, sizeof(buf)); 940 msg.msg_control = buf; 941 msg.msg_controllen = CMSG_SPACE(sizeof(u32)); 942 msg.msg_iov = io; 943 msg.msg_iovlen = 1; 944 hdr = CMSG_FIRSTHDR(&msg); 945 hdr->cmsg_level = SOL_ALG; 946 hdr->cmsg_type = ALG_SET_OP; 947 hdr->cmsg_len = CMSG_LEN(sizeof(u32)); 948 op = (u32 *) CMSG_DATA(hdr); 949 *op = type; 950 951 ret = sendmsg(ctx->skcipher->t, &msg, 0); 952 if (ret < 0) { 953 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 954 __func__, strerror(errno)); 955 return -1; 956 } 957 958 ret = read(ctx->skcipher->t, out, len); 959 if (ret < 0) { 960 wpa_printf(MSG_ERROR, "%s: read failed: %s", 961 __func__, strerror(errno)); 962 return -1; 963 } 964 if (ret < (ssize_t) len) { 965 wpa_printf(MSG_ERROR, 966 "%s: read did not return full data (%d/%d)", 967 __func__, (int) ret, (int) len); 968 return -1; 969 } 970 971 return 0; 972 } 973 974 975 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, 976 u8 *crypt, size_t len) 977 { 978 return crypto_cipher_oper(ctx, ALG_OP_ENCRYPT, plain, crypt, len); 979 } 980 981 982 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, 983 u8 *plain, size_t len) 984 { 985 return crypto_cipher_oper(ctx, ALG_OP_DECRYPT, crypt, plain, len); 986 } 987 988 989 void crypto_cipher_deinit(struct crypto_cipher *ctx) 990 { 991 if (ctx) { 992 linux_af_alg_skcipher_deinit(ctx->skcipher); 993 os_free(ctx); 994 } 995 } 996 997 998 int crypto_global_init(void) 999 { 1000 return 0; 1001 } 1002 1003 1004 void crypto_global_deinit(void) 1005 { 1006 } 1007