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 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 os_free(skip_buf); 584 585 msg.msg_control = NULL; 586 msg.msg_controllen = 0; 587 ret = recvmsg(skcipher->t, &msg, 0); 588 if (ret < 0) { 589 wpa_printf(MSG_ERROR, "%s: recvmsg failed: %s", 590 __func__, strerror(errno)); 591 linux_af_alg_skcipher_deinit(skcipher); 592 return -1; 593 } 594 linux_af_alg_skcipher_deinit(skcipher); 595 596 if ((size_t) ret < skip + data_len) { 597 wpa_printf(MSG_ERROR, 598 "%s: recvmsg did not return full data (%d/%d)", 599 __func__, (int) ret, (int) (skip + data_len)); 600 return -1; 601 } 602 603 return 0; 604 } 605 606 607 int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) 608 { 609 u8 pkey[8], next, tmp; 610 int i; 611 struct linux_af_alg_skcipher *skcipher; 612 char buf[CMSG_SPACE(sizeof(u32))]; 613 struct iovec io[1]; 614 struct msghdr msg; 615 struct cmsghdr *hdr; 616 ssize_t ret; 617 u32 *op; 618 int res = -1; 619 620 /* Add parity bits to the key */ 621 next = 0; 622 for (i = 0; i < 7; i++) { 623 tmp = key[i]; 624 pkey[i] = (tmp >> i) | next | 1; 625 next = tmp << (7 - i); 626 } 627 pkey[i] = next | 1; 628 629 skcipher = linux_af_alg_skcipher("ecb(des)", pkey, sizeof(pkey)); 630 if (!skcipher) 631 goto fail; 632 633 io[0].iov_base = (void *) clear; 634 io[0].iov_len = 8; 635 os_memset(&msg, 0, sizeof(msg)); 636 os_memset(buf, 0, sizeof(buf)); 637 msg.msg_control = buf; 638 msg.msg_controllen = CMSG_SPACE(sizeof(u32)); 639 msg.msg_iov = io; 640 msg.msg_iovlen = 1; 641 hdr = CMSG_FIRSTHDR(&msg); 642 hdr->cmsg_level = SOL_ALG; 643 hdr->cmsg_type = ALG_SET_OP; 644 hdr->cmsg_len = CMSG_LEN(sizeof(u32)); 645 op = (u32 *) CMSG_DATA(hdr); 646 *op = ALG_OP_ENCRYPT; 647 648 ret = sendmsg(skcipher->t, &msg, 0); 649 if (ret < 0) { 650 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 651 __func__, strerror(errno)); 652 goto fail; 653 } 654 655 ret = read(skcipher->t, cypher, 8); 656 if (ret < 0) { 657 wpa_printf(MSG_ERROR, "%s: read failed: %s", 658 __func__, strerror(errno)); 659 goto fail; 660 } 661 if (ret < 8) { 662 wpa_printf(MSG_ERROR, 663 "%s: read did not return full data (%d/8)", 664 __func__, (int) ret); 665 goto fail; 666 } 667 668 res = 0; 669 fail: 670 linux_af_alg_skcipher_deinit(skcipher); 671 return res; 672 } 673 674 675 static int aes_128_cbc_oper(const u8 *key, int enc, const u8 *iv, 676 u8 *data, size_t data_len) 677 { 678 struct linux_af_alg_skcipher *skcipher; 679 char buf[100]; 680 struct iovec io[1]; 681 struct msghdr msg; 682 struct cmsghdr *hdr; 683 ssize_t ret; 684 u32 *op; 685 struct af_alg_iv *alg_iv; 686 size_t iv_len = AES_BLOCK_SIZE; 687 688 skcipher = linux_af_alg_skcipher("cbc(aes)", key, 16); 689 if (!skcipher) 690 return -1; 691 692 io[0].iov_base = (void *) data; 693 io[0].iov_len = data_len; 694 os_memset(&msg, 0, sizeof(msg)); 695 os_memset(buf, 0, sizeof(buf)); 696 msg.msg_control = buf; 697 msg.msg_controllen = CMSG_SPACE(sizeof(u32)) + 698 CMSG_SPACE(sizeof(*alg_iv) + iv_len); 699 msg.msg_iov = io; 700 msg.msg_iovlen = 1; 701 702 hdr = CMSG_FIRSTHDR(&msg); 703 hdr->cmsg_level = SOL_ALG; 704 hdr->cmsg_type = ALG_SET_OP; 705 hdr->cmsg_len = CMSG_LEN(sizeof(u32)); 706 op = (u32 *) CMSG_DATA(hdr); 707 *op = enc ? ALG_OP_ENCRYPT : ALG_OP_DECRYPT; 708 709 hdr = CMSG_NXTHDR(&msg, hdr); 710 hdr->cmsg_level = SOL_ALG; 711 hdr->cmsg_type = ALG_SET_IV; 712 hdr->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv_len); 713 alg_iv = (struct af_alg_iv *) CMSG_DATA(hdr); 714 alg_iv->ivlen = iv_len; 715 os_memcpy(alg_iv->iv, iv, iv_len); 716 717 ret = sendmsg(skcipher->t, &msg, 0); 718 if (ret < 0) { 719 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 720 __func__, strerror(errno)); 721 linux_af_alg_skcipher_deinit(skcipher); 722 return -1; 723 } 724 725 ret = recvmsg(skcipher->t, &msg, 0); 726 if (ret < 0) { 727 wpa_printf(MSG_ERROR, "%s: recvmsg failed: %s", 728 __func__, strerror(errno)); 729 linux_af_alg_skcipher_deinit(skcipher); 730 return -1; 731 } 732 if ((size_t) ret < data_len) { 733 wpa_printf(MSG_ERROR, 734 "%s: recvmsg not return full data (%d/%d)", 735 __func__, (int) ret, (int) data_len); 736 linux_af_alg_skcipher_deinit(skcipher); 737 return -1; 738 } 739 740 linux_af_alg_skcipher_deinit(skcipher); 741 return 0; 742 } 743 744 745 int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) 746 { 747 return aes_128_cbc_oper(key, 1, iv, data, data_len); 748 } 749 750 751 int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) 752 { 753 return aes_128_cbc_oper(key, 0, iv, data, data_len); 754 } 755 756 757 int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem, 758 const u8 *addr[], const size_t *len, u8 *mac) 759 { 760 return linux_af_alg_hash_vector("cmac(aes)", key, key_len, num_elem, 761 addr, len, mac, AES_BLOCK_SIZE); 762 } 763 764 765 int omac1_aes_128_vector(const u8 *key, size_t num_elem, 766 const u8 *addr[], const size_t *len, u8 *mac) 767 { 768 return omac1_aes_vector(key, 16, num_elem, addr, len, mac); 769 } 770 771 772 int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac) 773 { 774 return omac1_aes_128_vector(key, 1, &data, &data_len, mac); 775 } 776 777 778 int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac) 779 { 780 return omac1_aes_vector(key, 32, 1, &data, &data_len, mac); 781 } 782 783 784 int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, 785 u8 *plain) 786 { 787 struct linux_af_alg_skcipher *skcipher; 788 char buf[100]; 789 struct iovec io[1]; 790 struct msghdr msg; 791 struct cmsghdr *hdr; 792 ssize_t ret; 793 u32 *op; 794 struct af_alg_iv *alg_iv; 795 size_t iv_len = 8; 796 797 skcipher = linux_af_alg_skcipher("kw(aes)", kek, kek_len); 798 if (!skcipher) 799 return -1; 800 801 io[0].iov_base = (void *) (cipher + iv_len); 802 io[0].iov_len = n * 8; 803 os_memset(&msg, 0, sizeof(msg)); 804 os_memset(buf, 0, sizeof(buf)); 805 msg.msg_control = buf; 806 msg.msg_controllen = CMSG_SPACE(sizeof(u32)) + 807 CMSG_SPACE(sizeof(*alg_iv) + iv_len); 808 msg.msg_iov = io; 809 msg.msg_iovlen = 1; 810 811 hdr = CMSG_FIRSTHDR(&msg); 812 hdr->cmsg_level = SOL_ALG; 813 hdr->cmsg_type = ALG_SET_OP; 814 hdr->cmsg_len = CMSG_LEN(sizeof(u32)); 815 op = (u32 *) CMSG_DATA(hdr); 816 *op = ALG_OP_DECRYPT; 817 818 hdr = CMSG_NXTHDR(&msg, hdr); 819 hdr->cmsg_level = SOL_ALG; 820 hdr->cmsg_type = ALG_SET_IV; 821 hdr->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv_len); 822 alg_iv = (struct af_alg_iv *) CMSG_DATA(hdr); 823 alg_iv->ivlen = iv_len; 824 os_memcpy(alg_iv->iv, cipher, iv_len); 825 826 ret = sendmsg(skcipher->t, &msg, 0); 827 if (ret < 0) { 828 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 829 __func__, strerror(errno)); 830 return -1; 831 } 832 833 ret = read(skcipher->t, plain, n * 8); 834 if (ret < 0) { 835 wpa_printf(MSG_ERROR, "%s: read failed: %s", 836 __func__, strerror(errno)); 837 linux_af_alg_skcipher_deinit(skcipher); 838 return -1; 839 } 840 if (ret < n * 8) { 841 wpa_printf(MSG_ERROR, 842 "%s: read not return full data (%d/%d)", 843 __func__, (int) ret, n * 8); 844 linux_af_alg_skcipher_deinit(skcipher); 845 return -1; 846 } 847 848 linux_af_alg_skcipher_deinit(skcipher); 849 return 0; 850 } 851 852 853 struct crypto_cipher { 854 struct linux_af_alg_skcipher *skcipher; 855 }; 856 857 858 struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, 859 const u8 *iv, const u8 *key, 860 size_t key_len) 861 { 862 struct crypto_cipher *ctx; 863 const char *name; 864 struct af_alg_iv *alg_iv; 865 size_t iv_len = 0; 866 char buf[100]; 867 struct msghdr msg; 868 struct cmsghdr *hdr; 869 ssize_t ret; 870 871 ctx = os_zalloc(sizeof(*ctx)); 872 if (!ctx) 873 return NULL; 874 875 switch (alg) { 876 case CRYPTO_CIPHER_ALG_RC4: 877 name = "ecb(arc4)"; 878 break; 879 case CRYPTO_CIPHER_ALG_AES: 880 name = "cbc(aes)"; 881 iv_len = AES_BLOCK_SIZE; 882 break; 883 case CRYPTO_CIPHER_ALG_3DES: 884 name = "cbc(des3_ede)"; 885 iv_len = 8; 886 break; 887 case CRYPTO_CIPHER_ALG_DES: 888 name = "cbc(des)"; 889 iv_len = 8; 890 break; 891 default: 892 os_free(ctx); 893 return NULL; 894 } 895 896 ctx->skcipher = linux_af_alg_skcipher(name, key, key_len); 897 if (!ctx->skcipher) { 898 os_free(ctx); 899 return NULL; 900 } 901 902 if (iv && iv_len) { 903 os_memset(&msg, 0, sizeof(msg)); 904 os_memset(buf, 0, sizeof(buf)); 905 msg.msg_control = buf; 906 msg.msg_controllen = CMSG_SPACE(sizeof(*alg_iv) + iv_len); 907 hdr = CMSG_FIRSTHDR(&msg); 908 hdr->cmsg_level = SOL_ALG; 909 hdr->cmsg_type = ALG_SET_IV; 910 hdr->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv_len); 911 alg_iv = (struct af_alg_iv *) CMSG_DATA(hdr); 912 alg_iv->ivlen = iv_len; 913 os_memcpy(alg_iv->iv, iv, iv_len); 914 915 ret = sendmsg(ctx->skcipher->t, &msg, 0); 916 if (ret < 0) { 917 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 918 __func__, strerror(errno)); 919 linux_af_alg_skcipher_deinit(ctx->skcipher); 920 os_free(ctx); 921 return NULL; 922 } 923 } 924 925 return ctx; 926 } 927 928 929 static int crypto_cipher_oper(struct crypto_cipher *ctx, u32 type, const u8 *in, 930 u8 *out, size_t len) 931 { 932 char buf[CMSG_SPACE(sizeof(u32))]; 933 struct iovec io[1]; 934 struct msghdr msg; 935 struct cmsghdr *hdr; 936 ssize_t ret; 937 u32 *op; 938 939 io[0].iov_base = (void *) in; 940 io[0].iov_len = len; 941 os_memset(&msg, 0, sizeof(msg)); 942 os_memset(buf, 0, sizeof(buf)); 943 msg.msg_control = buf; 944 msg.msg_controllen = CMSG_SPACE(sizeof(u32)); 945 msg.msg_iov = io; 946 msg.msg_iovlen = 1; 947 hdr = CMSG_FIRSTHDR(&msg); 948 hdr->cmsg_level = SOL_ALG; 949 hdr->cmsg_type = ALG_SET_OP; 950 hdr->cmsg_len = CMSG_LEN(sizeof(u32)); 951 op = (u32 *) CMSG_DATA(hdr); 952 *op = type; 953 954 ret = sendmsg(ctx->skcipher->t, &msg, 0); 955 if (ret < 0) { 956 wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s", 957 __func__, strerror(errno)); 958 return -1; 959 } 960 961 ret = read(ctx->skcipher->t, out, len); 962 if (ret < 0) { 963 wpa_printf(MSG_ERROR, "%s: read failed: %s", 964 __func__, strerror(errno)); 965 return -1; 966 } 967 if (ret < (ssize_t) len) { 968 wpa_printf(MSG_ERROR, 969 "%s: read did not return full data (%d/%d)", 970 __func__, (int) ret, (int) len); 971 return -1; 972 } 973 974 return 0; 975 } 976 977 978 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, 979 u8 *crypt, size_t len) 980 { 981 return crypto_cipher_oper(ctx, ALG_OP_ENCRYPT, plain, crypt, len); 982 } 983 984 985 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, 986 u8 *plain, size_t len) 987 { 988 return crypto_cipher_oper(ctx, ALG_OP_DECRYPT, crypt, plain, len); 989 } 990 991 992 void crypto_cipher_deinit(struct crypto_cipher *ctx) 993 { 994 if (ctx) { 995 linux_af_alg_skcipher_deinit(ctx->skcipher); 996 os_free(ctx); 997 } 998 } 999 1000 1001 int crypto_global_init(void) 1002 { 1003 return 0; 1004 } 1005 1006 1007 void crypto_global_deinit(void) 1008 { 1009 } 1010