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 *len = ctx->mac_len; 367 crypto_hash_deinit(ctx); 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 390 if (TEST_FAIL()) 391 return -1; 392 return 0; 393 } 394 395 396 struct linux_af_alg_skcipher { 397 int s; 398 int t; 399 }; 400 401 402 static void linux_af_alg_skcipher_deinit(struct linux_af_alg_skcipher *skcipher) 403 { 404 if (!skcipher) 405 return; 406 if (skcipher->s >= 0) 407 close(skcipher->s); 408 if (skcipher->t >= 0) 409 close(skcipher->t); 410 os_free(skcipher); 411 } 412 413 414 static struct linux_af_alg_skcipher * 415 linux_af_alg_skcipher(const char *alg, const u8 *key, size_t key_len) 416 { 417 struct linux_af_alg_skcipher *skcipher; 418 419 skcipher = os_zalloc(sizeof(*skcipher)); 420 if (!skcipher) 421 goto fail; 422 skcipher->t = -1; 423 424 skcipher->s = linux_af_alg_socket("skcipher", alg); 425 if (skcipher->s < 0) 426 goto fail; 427 428 if (setsockopt(skcipher->s, SOL_ALG, ALG_SET_KEY, key, key_len) < 0) { 429 wpa_printf(MSG_ERROR, "%s: setsockopt(ALG_SET_KEY) failed: %s", 430 __func__, strerror(errno)); 431 goto fail; 432 } 433 434 skcipher->t = accept(skcipher->s, NULL, NULL); 435 if (skcipher->t < 0) { 436 wpa_printf(MSG_ERROR, "%s: accept on AF_ALG socket failed: %s", 437 __func__, strerror(errno)); 438 goto fail; 439 } 440 441 return skcipher; 442 fail: 443 linux_af_alg_skcipher_deinit(skcipher); 444 return NULL; 445 } 446 447 448 static int linux_af_alg_skcipher_oper(struct linux_af_alg_skcipher *skcipher, 449 int enc, const u8 *in, u8 *out) 450 { 451 char buf[CMSG_SPACE(sizeof(u32))]; 452 struct iovec io[1]; 453 struct msghdr msg; 454 struct cmsghdr *hdr; 455 ssize_t ret; 456 u32 *op; 457 458 io[0].iov_base = (void *) in; 459 io[0].iov_len = AES_BLOCK_SIZE; 460 os_memset(&msg, 0, sizeof(msg)); 461 os_memset(buf, 0, sizeof(buf)); 462 msg.msg_control = buf; 463 msg.msg_controllen = CMSG_SPACE(sizeof(u32)); 464 msg.msg_iov = io; 465 msg.msg_iovlen = 1; 466 hdr = CMSG_FIRSTHDR(&msg); 467 hdr->cmsg_level = SOL_ALG; 468 hdr->cmsg_type = ALG_SET_OP; 469 hdr->cmsg_len = CMSG_LEN(sizeof(u32)); 470 op = (u32 *) CMSG_DATA(hdr); 471 *op = enc ? ALG_OP_ENCRYPT : ALG_OP_DECRYPT; 472 473 ret = sendmsg(skcipher->t, &msg, 0); 474 if (ret < 0) { 475 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 476 __func__, strerror(errno)); 477 return -1; 478 } 479 480 ret = read(skcipher->t, out, AES_BLOCK_SIZE); 481 if (ret < 0) { 482 wpa_printf(MSG_ERROR, "%s: read failed: %s", 483 __func__, strerror(errno)); 484 return -1; 485 } 486 if (ret < AES_BLOCK_SIZE) { 487 wpa_printf(MSG_ERROR, 488 "%s: read did not return full data (%d/%d)", 489 __func__, (int) ret, AES_BLOCK_SIZE); 490 return -1; 491 } 492 493 return 0; 494 } 495 496 497 void * aes_encrypt_init(const u8 *key, size_t len) 498 { 499 return linux_af_alg_skcipher("ecb(aes)", key, len); 500 } 501 502 503 int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) 504 { 505 struct linux_af_alg_skcipher *skcipher = ctx; 506 507 return linux_af_alg_skcipher_oper(skcipher, 1, plain, crypt); 508 } 509 510 511 void aes_encrypt_deinit(void *ctx) 512 { 513 linux_af_alg_skcipher_deinit(ctx); 514 } 515 516 517 void * aes_decrypt_init(const u8 *key, size_t len) 518 { 519 return linux_af_alg_skcipher("ecb(aes)", key, len); 520 } 521 522 523 int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) 524 { 525 struct linux_af_alg_skcipher *skcipher = ctx; 526 527 return linux_af_alg_skcipher_oper(skcipher, 0, crypt, plain); 528 } 529 530 531 void aes_decrypt_deinit(void *ctx) 532 { 533 linux_af_alg_skcipher_deinit(ctx); 534 } 535 536 537 int rc4_skip(const u8 *key, size_t keylen, size_t skip, 538 u8 *data, size_t data_len) 539 { 540 struct linux_af_alg_skcipher *skcipher; 541 u8 *skip_buf; 542 char buf[CMSG_SPACE(sizeof(u32))]; 543 struct iovec io[2]; 544 struct msghdr msg; 545 struct cmsghdr *hdr; 546 ssize_t ret; 547 u32 *op; 548 549 skip_buf = os_zalloc(skip + 1); 550 if (!skip_buf) 551 return -1; 552 skcipher = linux_af_alg_skcipher("ecb(arc4)", key, keylen); 553 if (!skcipher) { 554 os_free(skip_buf); 555 return -1; 556 } 557 558 io[0].iov_base = skip_buf; 559 io[0].iov_len = skip; 560 io[1].iov_base = data; 561 io[1].iov_len = data_len; 562 os_memset(&msg, 0, sizeof(msg)); 563 os_memset(buf, 0, sizeof(buf)); 564 msg.msg_control = buf; 565 msg.msg_controllen = CMSG_SPACE(sizeof(u32)); 566 msg.msg_iov = io; 567 msg.msg_iovlen = 2; 568 hdr = CMSG_FIRSTHDR(&msg); 569 hdr->cmsg_level = SOL_ALG; 570 hdr->cmsg_type = ALG_SET_OP; 571 hdr->cmsg_len = CMSG_LEN(sizeof(u32)); 572 op = (u32 *) CMSG_DATA(hdr); 573 *op = ALG_OP_ENCRYPT; 574 575 ret = sendmsg(skcipher->t, &msg, 0); 576 if (ret < 0) { 577 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 578 __func__, strerror(errno)); 579 os_free(skip_buf); 580 linux_af_alg_skcipher_deinit(skcipher); 581 return -1; 582 } 583 584 msg.msg_control = NULL; 585 msg.msg_controllen = 0; 586 ret = recvmsg(skcipher->t, &msg, 0); 587 if (ret < 0) { 588 wpa_printf(MSG_ERROR, "%s: recvmsg failed: %s", 589 __func__, strerror(errno)); 590 os_free(skip_buf); 591 linux_af_alg_skcipher_deinit(skcipher); 592 return -1; 593 } 594 os_free(skip_buf); 595 linux_af_alg_skcipher_deinit(skcipher); 596 597 if ((size_t) ret < skip + data_len) { 598 wpa_printf(MSG_ERROR, 599 "%s: recvmsg did not return full data (%d/%d)", 600 __func__, (int) ret, (int) (skip + data_len)); 601 return -1; 602 } 603 604 return 0; 605 } 606 607 608 int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) 609 { 610 u8 pkey[8], next, tmp; 611 int i; 612 struct linux_af_alg_skcipher *skcipher; 613 char buf[CMSG_SPACE(sizeof(u32))]; 614 struct iovec io[1]; 615 struct msghdr msg; 616 struct cmsghdr *hdr; 617 ssize_t ret; 618 u32 *op; 619 int res = -1; 620 621 /* Add parity bits to the key */ 622 next = 0; 623 for (i = 0; i < 7; i++) { 624 tmp = key[i]; 625 pkey[i] = (tmp >> i) | next | 1; 626 next = tmp << (7 - i); 627 } 628 pkey[i] = next | 1; 629 630 skcipher = linux_af_alg_skcipher("ecb(des)", pkey, sizeof(pkey)); 631 if (!skcipher) 632 goto fail; 633 634 io[0].iov_base = (void *) clear; 635 io[0].iov_len = 8; 636 os_memset(&msg, 0, sizeof(msg)); 637 os_memset(buf, 0, sizeof(buf)); 638 msg.msg_control = buf; 639 msg.msg_controllen = CMSG_SPACE(sizeof(u32)); 640 msg.msg_iov = io; 641 msg.msg_iovlen = 1; 642 hdr = CMSG_FIRSTHDR(&msg); 643 hdr->cmsg_level = SOL_ALG; 644 hdr->cmsg_type = ALG_SET_OP; 645 hdr->cmsg_len = CMSG_LEN(sizeof(u32)); 646 op = (u32 *) CMSG_DATA(hdr); 647 *op = ALG_OP_ENCRYPT; 648 649 ret = sendmsg(skcipher->t, &msg, 0); 650 if (ret < 0) { 651 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 652 __func__, strerror(errno)); 653 goto fail; 654 } 655 656 ret = read(skcipher->t, cypher, 8); 657 if (ret < 0) { 658 wpa_printf(MSG_ERROR, "%s: read failed: %s", 659 __func__, strerror(errno)); 660 goto fail; 661 } 662 if (ret < 8) { 663 wpa_printf(MSG_ERROR, 664 "%s: read did not return full data (%d/8)", 665 __func__, (int) ret); 666 goto fail; 667 } 668 669 res = 0; 670 fail: 671 linux_af_alg_skcipher_deinit(skcipher); 672 return res; 673 } 674 675 676 static int aes_128_cbc_oper(const u8 *key, int enc, const u8 *iv, 677 u8 *data, size_t data_len) 678 { 679 struct linux_af_alg_skcipher *skcipher; 680 char buf[100]; 681 struct iovec io[1]; 682 struct msghdr msg; 683 struct cmsghdr *hdr; 684 ssize_t ret; 685 u32 *op; 686 struct af_alg_iv *alg_iv; 687 size_t iv_len = AES_BLOCK_SIZE; 688 689 skcipher = linux_af_alg_skcipher("cbc(aes)", key, 16); 690 if (!skcipher) 691 return -1; 692 693 io[0].iov_base = (void *) data; 694 io[0].iov_len = data_len; 695 os_memset(&msg, 0, sizeof(msg)); 696 os_memset(buf, 0, sizeof(buf)); 697 msg.msg_control = buf; 698 msg.msg_controllen = CMSG_SPACE(sizeof(u32)) + 699 CMSG_SPACE(sizeof(*alg_iv) + iv_len); 700 msg.msg_iov = io; 701 msg.msg_iovlen = 1; 702 703 hdr = CMSG_FIRSTHDR(&msg); 704 hdr->cmsg_level = SOL_ALG; 705 hdr->cmsg_type = ALG_SET_OP; 706 hdr->cmsg_len = CMSG_LEN(sizeof(u32)); 707 op = (u32 *) CMSG_DATA(hdr); 708 *op = enc ? ALG_OP_ENCRYPT : ALG_OP_DECRYPT; 709 710 hdr = CMSG_NXTHDR(&msg, hdr); 711 hdr->cmsg_level = SOL_ALG; 712 hdr->cmsg_type = ALG_SET_IV; 713 hdr->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv_len); 714 alg_iv = (struct af_alg_iv *) CMSG_DATA(hdr); 715 alg_iv->ivlen = iv_len; 716 os_memcpy(alg_iv->iv, iv, iv_len); 717 718 ret = sendmsg(skcipher->t, &msg, 0); 719 if (ret < 0) { 720 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 721 __func__, strerror(errno)); 722 linux_af_alg_skcipher_deinit(skcipher); 723 return -1; 724 } 725 726 ret = recvmsg(skcipher->t, &msg, 0); 727 if (ret < 0) { 728 wpa_printf(MSG_ERROR, "%s: recvmsg failed: %s", 729 __func__, strerror(errno)); 730 linux_af_alg_skcipher_deinit(skcipher); 731 return -1; 732 } 733 if ((size_t) ret < data_len) { 734 wpa_printf(MSG_ERROR, 735 "%s: recvmsg not return full data (%d/%d)", 736 __func__, (int) ret, (int) data_len); 737 linux_af_alg_skcipher_deinit(skcipher); 738 return -1; 739 } 740 741 linux_af_alg_skcipher_deinit(skcipher); 742 return 0; 743 } 744 745 746 int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) 747 { 748 return aes_128_cbc_oper(key, 1, iv, data, data_len); 749 } 750 751 752 int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) 753 { 754 return aes_128_cbc_oper(key, 0, iv, data, data_len); 755 } 756 757 758 int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem, 759 const u8 *addr[], const size_t *len, u8 *mac) 760 { 761 return linux_af_alg_hash_vector("cmac(aes)", key, key_len, num_elem, 762 addr, len, mac, AES_BLOCK_SIZE); 763 } 764 765 766 int omac1_aes_128_vector(const u8 *key, size_t num_elem, 767 const u8 *addr[], const size_t *len, u8 *mac) 768 { 769 return omac1_aes_vector(key, 16, num_elem, addr, len, mac); 770 } 771 772 773 int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac) 774 { 775 return omac1_aes_128_vector(key, 1, &data, &data_len, mac); 776 } 777 778 779 int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac) 780 { 781 return omac1_aes_vector(key, 32, 1, &data, &data_len, mac); 782 } 783 784 785 int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, 786 u8 *plain) 787 { 788 struct linux_af_alg_skcipher *skcipher; 789 char buf[100]; 790 struct iovec io[1]; 791 struct msghdr msg; 792 struct cmsghdr *hdr; 793 ssize_t ret; 794 u32 *op; 795 struct af_alg_iv *alg_iv; 796 size_t iv_len = 8; 797 798 skcipher = linux_af_alg_skcipher("kw(aes)", kek, kek_len); 799 if (!skcipher) 800 return -1; 801 802 io[0].iov_base = (void *) (cipher + iv_len); 803 io[0].iov_len = n * 8; 804 os_memset(&msg, 0, sizeof(msg)); 805 os_memset(buf, 0, sizeof(buf)); 806 msg.msg_control = buf; 807 msg.msg_controllen = CMSG_SPACE(sizeof(u32)) + 808 CMSG_SPACE(sizeof(*alg_iv) + iv_len); 809 msg.msg_iov = io; 810 msg.msg_iovlen = 1; 811 812 hdr = CMSG_FIRSTHDR(&msg); 813 hdr->cmsg_level = SOL_ALG; 814 hdr->cmsg_type = ALG_SET_OP; 815 hdr->cmsg_len = CMSG_LEN(sizeof(u32)); 816 op = (u32 *) CMSG_DATA(hdr); 817 *op = ALG_OP_DECRYPT; 818 819 hdr = CMSG_NXTHDR(&msg, hdr); 820 hdr->cmsg_level = SOL_ALG; 821 hdr->cmsg_type = ALG_SET_IV; 822 hdr->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv_len); 823 alg_iv = (struct af_alg_iv *) CMSG_DATA(hdr); 824 alg_iv->ivlen = iv_len; 825 os_memcpy(alg_iv->iv, cipher, iv_len); 826 827 ret = sendmsg(skcipher->t, &msg, 0); 828 if (ret < 0) { 829 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 830 __func__, strerror(errno)); 831 return -1; 832 } 833 834 ret = read(skcipher->t, plain, n * 8); 835 if (ret < 0) { 836 wpa_printf(MSG_ERROR, "%s: read failed: %s", 837 __func__, strerror(errno)); 838 linux_af_alg_skcipher_deinit(skcipher); 839 return -1; 840 } 841 if (ret < n * 8) { 842 wpa_printf(MSG_ERROR, 843 "%s: read not return full data (%d/%d)", 844 __func__, (int) ret, n * 8); 845 linux_af_alg_skcipher_deinit(skcipher); 846 return -1; 847 } 848 849 linux_af_alg_skcipher_deinit(skcipher); 850 return 0; 851 } 852 853 854 struct crypto_cipher { 855 struct linux_af_alg_skcipher *skcipher; 856 }; 857 858 859 struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, 860 const u8 *iv, const u8 *key, 861 size_t key_len) 862 { 863 struct crypto_cipher *ctx; 864 const char *name; 865 struct af_alg_iv *alg_iv; 866 size_t iv_len = 0; 867 char buf[100]; 868 struct msghdr msg; 869 struct cmsghdr *hdr; 870 ssize_t ret; 871 872 ctx = os_zalloc(sizeof(*ctx)); 873 if (!ctx) 874 return NULL; 875 876 switch (alg) { 877 case CRYPTO_CIPHER_ALG_RC4: 878 name = "ecb(arc4)"; 879 break; 880 case CRYPTO_CIPHER_ALG_AES: 881 name = "cbc(aes)"; 882 iv_len = AES_BLOCK_SIZE; 883 break; 884 case CRYPTO_CIPHER_ALG_3DES: 885 name = "cbc(des3_ede)"; 886 iv_len = 8; 887 break; 888 case CRYPTO_CIPHER_ALG_DES: 889 name = "cbc(des)"; 890 iv_len = 8; 891 break; 892 default: 893 os_free(ctx); 894 return NULL; 895 } 896 897 ctx->skcipher = linux_af_alg_skcipher(name, key, key_len); 898 if (!ctx->skcipher) { 899 os_free(ctx); 900 return NULL; 901 } 902 903 if (iv && iv_len) { 904 os_memset(&msg, 0, sizeof(msg)); 905 os_memset(buf, 0, sizeof(buf)); 906 msg.msg_control = buf; 907 msg.msg_controllen = CMSG_SPACE(sizeof(*alg_iv) + iv_len); 908 hdr = CMSG_FIRSTHDR(&msg); 909 hdr->cmsg_level = SOL_ALG; 910 hdr->cmsg_type = ALG_SET_IV; 911 hdr->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv_len); 912 alg_iv = (struct af_alg_iv *) CMSG_DATA(hdr); 913 alg_iv->ivlen = iv_len; 914 os_memcpy(alg_iv->iv, iv, iv_len); 915 916 ret = sendmsg(ctx->skcipher->t, &msg, 0); 917 if (ret < 0) { 918 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 919 __func__, strerror(errno)); 920 linux_af_alg_skcipher_deinit(ctx->skcipher); 921 os_free(ctx); 922 return NULL; 923 } 924 } 925 926 return ctx; 927 } 928 929 930 static int crypto_cipher_oper(struct crypto_cipher *ctx, u32 type, const u8 *in, 931 u8 *out, size_t len) 932 { 933 char buf[CMSG_SPACE(sizeof(u32))]; 934 struct iovec io[1]; 935 struct msghdr msg; 936 struct cmsghdr *hdr; 937 ssize_t ret; 938 u32 *op; 939 940 io[0].iov_base = (void *) in; 941 io[0].iov_len = len; 942 os_memset(&msg, 0, sizeof(msg)); 943 os_memset(buf, 0, sizeof(buf)); 944 msg.msg_control = buf; 945 msg.msg_controllen = CMSG_SPACE(sizeof(u32)); 946 msg.msg_iov = io; 947 msg.msg_iovlen = 1; 948 hdr = CMSG_FIRSTHDR(&msg); 949 hdr->cmsg_level = SOL_ALG; 950 hdr->cmsg_type = ALG_SET_OP; 951 hdr->cmsg_len = CMSG_LEN(sizeof(u32)); 952 op = (u32 *) CMSG_DATA(hdr); 953 *op = type; 954 955 ret = sendmsg(ctx->skcipher->t, &msg, 0); 956 if (ret < 0) { 957 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 958 __func__, strerror(errno)); 959 return -1; 960 } 961 962 ret = read(ctx->skcipher->t, out, len); 963 if (ret < 0) { 964 wpa_printf(MSG_ERROR, "%s: read failed: %s", 965 __func__, strerror(errno)); 966 return -1; 967 } 968 if (ret < (ssize_t) len) { 969 wpa_printf(MSG_ERROR, 970 "%s: read did not return full data (%d/%d)", 971 __func__, (int) ret, (int) len); 972 return -1; 973 } 974 975 return 0; 976 } 977 978 979 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, 980 u8 *crypt, size_t len) 981 { 982 return crypto_cipher_oper(ctx, ALG_OP_ENCRYPT, plain, crypt, len); 983 } 984 985 986 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, 987 u8 *plain, size_t len) 988 { 989 return crypto_cipher_oper(ctx, ALG_OP_DECRYPT, crypt, plain, len); 990 } 991 992 993 void crypto_cipher_deinit(struct crypto_cipher *ctx) 994 { 995 if (ctx) { 996 linux_af_alg_skcipher_deinit(ctx->skcipher); 997 os_free(ctx); 998 } 999 } 1000 1001 1002 int crypto_global_init(void) 1003 { 1004 return 0; 1005 } 1006 1007 1008 void crypto_global_deinit(void) 1009 { 1010 } 1011 1012 1013 void crypto_unload(void) 1014 { 1015 } 1016