Home | History | Annotate | Download | only in crypto
      1 /*
      2  * Crypto wrapper for Linux kernel AF_ALG
      3  * Copyright (c) 2017, Jouni Malinen <j (at) 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