Пример #1
0
/*
 *
 * xsocks UDP Response
 * +------+----------+----------+----------+
 * | ATYP | DST.ADDR | DST.PORT |   DATA   |
 * +------+----------+----------+----------+
 * |  1   | Variable |    2     | Variable |
 * +------+----------+----------+----------+
 *
 */
static void
server_recv_cb(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags) {
    if (nread > 0) {
        struct client_context *client = handle->data;
        reset_timer(client);

        int mlen = nread - PRIMITIVE_BYTES;
        uint8_t *m = (uint8_t *)buf->base;
        int rc = crypto_decrypt(m, (uint8_t *)buf->base, nread);
        if (rc) {
            logger_log(LOG_ERR, "invalid packet");
            dump_hex(buf->base, nread, "server recv");
            goto err;
        }

        m -= 3;
        mlen += 3;
        memcpy(m, "\x0\x0\x0", 3); // RSV + FRAG

        forward_to_client(client, m , mlen);

        return;

    } else {
        goto err;
    }

err:
    free(buf->base - 3);
}
Пример #2
0
/*
 *
 * xsocks UDP Response
 * +------+----------+----------+----------+
 * | ATYP | DST.ADDR | DST.PORT |   DATA   |
 * +------+----------+----------+----------+
 * |  1   | Variable |    2     | Variable |
 * +------+----------+----------+----------+
 *
 */
static void
server_recv_cb(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags) {
    if (nread > 0) {
        struct client_context *client = handle->data;
        reset_timer(client);

        int mlen = nread - PRIMITIVE_BYTES;
        uint8_t *m = (uint8_t *)buf->base;
        int rc = crypto_decrypt(m, (uint8_t *)buf->base, nread);
        if (rc) {
            logger_log(LOG_ERR, "invalid packet");
            goto err;
        }

        memmove(m, m + addrlen, mlen - addrlen);
        mlen -= addrlen;

        forward_to_client(client, m , mlen);

    } else {
        goto err;
    }

    return;

err:
    free(buf->base);
}
Пример #3
0
void
test_crypto (enum transform which)
{
  u_int8_t buf[256];
  struct crypto_xf *xf;
  struct keystate *ks;
  enum cryptoerr err;

  xf = crypto_get (which);
  printf ("Testing %s: ", xf->name);

  SET_KEY (buf, xf->keymax);
  ks = crypto_init (xf, buf, xf->keymax, &err);
  if (!ks)
    {
      printf ("FAILED (init %d)", err);
      goto fail;
    }
  SET_KEY (buf, sizeof (buf));
  crypto_init_iv (ks, buf, xf->blocksize);
  crypto_encrypt (ks, buf, sizeof (buf));
  dump_buf (buf, sizeof buf);
  crypto_decrypt (ks, buf, sizeof (buf));
  if (!verify_buf (buf, sizeof (buf)))
    printf ("FAILED ");
  else
    printf ("OKAY ");

  free (ks);

 fail:
  printf ("\n");
  return;
}
Пример #4
0
int FMT_crypt_load(const char *fname, byte_string_t bs, const char *password)
{
    FILE *infp;
    byte_string_t K, W;
    int result = 0;

    infp = fopen(fname, "r");
    if (!infp) return 0;

    byte_string_set(K, password);

    advance_to("W:", infp);
    mime_get(W, infp);

    if (1 != crypto_decrypt(bs, W, K)) {
	fprintf(stderr, "crypto_decrypt() failed!\n");
    } else {
	result = 1;
    }

    fclose(infp);

    byte_string_clear(K);
    byte_string_clear(W);
    return result;
}
Пример #5
0
static void
inet_recv_cb(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf,
             const struct sockaddr *addr, unsigned flags)
{
    struct tundev_context *ctx = container_of(handle, struct tundev_context,
                                              inet_udp);

    if (nread > 0) {
        uint8_t *m = (uint8_t *)buf->base;
        ssize_t mlen = nread - PRIMITIVE_BYTES;

        int rc = crypto_decrypt(m, (uint8_t *)buf->base, nread);
        if (rc) {
            int port = 0;
            char remote[INET_ADDRSTRLEN + 1];
            port = ip_name(addr, remote, sizeof(remote));
            logger_log(LOG_ERR, "Invalid udp packet from %s:%d", remote, port);
            return;
        }

        if (mode == xTUN_SERVER) {
            struct iphdr *iphdr = (struct iphdr *) m;

            in_addr_t client_network = iphdr->saddr & htonl(ctx->tun->netmask);
            if (client_network != ctx->tun->network) {
                char *a = inet_ntoa(*(struct in_addr *) &iphdr->saddr);
                logger_log(LOG_ERR, "Invalid client: %s", a);
                return;
            }

            // TODO: Compare source address
            uv_rwlock_rdlock(&rwlock);
            struct peer *peer = lookup_peer(iphdr->saddr, peers);
            uv_rwlock_rdunlock(&rwlock);
            if (peer == NULL) {
                char saddr[24] = {0}, daddr[24] = {0};
                parse_addr(iphdr, saddr, daddr);
                logger_log(LOG_WARNING, "[UDP] Cache miss: %s -> %s", saddr, daddr);
                uv_rwlock_wrlock(&rwlock);
                peer = save_peer(iphdr->saddr, (struct sockaddr *) addr, peers);
                uv_rwlock_wrunlock(&rwlock);

            } else {
                if (memcmp(&peer->remote_addr, addr, sizeof(*addr))) {
                    peer->remote_addr = *addr;
                }
            }
            peer->protocol = xTUN_UDP;
        }

        network_to_tun(ctx->tunfd, m, mlen);
    }
}
Пример #6
0
/*crypto_encrypt加密与crypto_decrypt解密验证*/
int sss_test1()
{
	char * data_in = NULL;
	int data_in_len = 128*10/8;
	CRYPTO_ENCRYPT_ALGORITHM alg = CRYPTO_ENCRYPT_ALGORITHM_AES_ECB;
	char * out_data = NULL;
	int out_data_len = 128*10/8;
	char * decrypto_resul = NULL;
	int ret = 0;

	data_in = (char*)malloc(data_in_len);
	decrypto_resul = (char*)malloc(data_in_len);
	out_data = (char*)malloc(out_data_len);
	if(!data_in || !decrypto_resul || !out_data)
	{
		ret = -1;
		goto OUT;
	}
	memset(data_in, 1, data_in_len);
	memset(decrypto_resul, 0, data_in_len);
	memset(out_data, 0, out_data_len);

	ret = crypto_encrypt(data_in, data_in_len, alg, (char *)sha1_in_key,
		AES_KEY_LEN, out_data, &out_data_len);
	if(BSP_ERROR == ret)
	{
		security_print("function : %s -- linenum : %d -- retval : %X\n", ret);
		goto OUT;
	}

	ret = crypto_decrypt(out_data, out_data_len, alg, (char *)sha1_in_key,
		AES_KEY_LEN, decrypto_resul, &data_in_len);
	if(BSP_ERROR == ret)
	{
		security_print("function : %s -- linenum : %d -- retval : %X\n", ret);
		goto OUT;
	}

	ret = memcmp(data_in, decrypto_resul, (unsigned) data_in_len);
	if(BSP_ERROR == ret)
	{
		security_print("function : %s -- linenum : %d -- retval : %X\n", ret);
		goto OUT;
	}
OUT:
	free(data_in);
	free(out_data);
	free(decrypto_resul);

	return ret;
}
Пример #7
0
static void
remote_recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
    struct remote_context *remote;
    struct client_context *client;

    remote = stream->data;
    client = remote->client;

    if (nread > 0) {
        reset_timer(remote);
        struct packet *packet = &remote->packet;
        int rc = packet_filter(packet, buf->base, nread);
        if (rc == PACKET_COMPLETED) {
            int clen = packet->size;
            int mlen = packet->size - PRIMITIVE_BYTES;
            uint8_t *c = packet->buf, *m = packet->buf;

            assert(mlen > 0 && mlen <= MAX_PACKET_SIZE - PRIMITIVE_BYTES);

            int err = crypto_decrypt(m, c, clen);
            if (err) {
                goto error;
            }

            uv_read_stop(&remote->handle.stream);
            forward_to_client(client, m, mlen);

        } else if (rc == PACKET_INVALID) {
            goto error;
        }

    } else if (nread < 0){
        if (nread != UV_EOF && verbose) {
            char addrbuf[INET6_ADDRSTRLEN + 1];
            int port = ip_name(&client->target_addr, addrbuf, sizeof(addrbuf));
            logger_log(LOG_ERR, "receive from %s:%d failed: %s", addrbuf, port, uv_strerror(nread));
        }
        close_client(client);
        close_remote(remote);
    }

    return;

error:
    logger_log(LOG_ERR, "invalid tcp packet");
    if (verbose) {
        dump_hex(buf->base, nread, "invalid tcp Packet");
    }
    close_client(client);
    close_remote(remote);
}
Пример #8
0
static GByteArray *
decrypt_key (const char *cipher,
             int key_type,
             GByteArray *data,
             const char *iv,
             const char *password,
             GError **error)
{
	char *bin_iv = NULL;
	gsize bin_iv_len = 0;
	char *key = NULL;
	gsize key_len = 0;
	char *output = NULL;
	gsize decrypted_len = 0;
	GByteArray *decrypted = NULL;

	g_return_val_if_fail (password != NULL, NULL);

	bin_iv = convert_iv (iv, &bin_iv_len, error);
	if (!bin_iv)
		return NULL;

	/* Convert the password and IV into a DES or AES key */
	key = make_des_aes_key (cipher, bin_iv, bin_iv_len, password, &key_len, error);
	if (!key || !key_len)
		goto out;

	output = crypto_decrypt (cipher, key_type,
	                         data,
	                         bin_iv, bin_iv_len,
	                         key, key_len,
	                         &decrypted_len,
	                         error);
	if (output && decrypted_len) {
		decrypted = g_byte_array_sized_new (decrypted_len);
		g_byte_array_append (decrypted, (guint8 *) output, decrypted_len);
	}

out:
	/* Don't leak stale key material */
	if (key)
		memset (key, 0, key_len);
	g_free (output);
	g_free (key);
	g_free (bin_iv);

	return decrypted;
}
Пример #9
0
static void
source_recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
    struct source_context *source = stream->data;
    struct target_context *target = source->target;

    if (nread > 0) {
        if (mode == TUNNEL_MODE_CLIENT) {
            int clen = nread + PRIMITIVE_BYTES;
            uint8_t *c = source->packet.buf + HEADER_BYTES;
            int rc = crypto_encrypt(c, (uint8_t*)buf->base, nread);
            if (rc) {
                goto error;
            }
            forward_to_target(target, c, clen);

        } else {
            struct packet *packet = &source->packet;
            int rc = packet_filter(packet, buf->base, nread);
            if (rc == PACKET_COMPLETED) {
                uint8_t *m = packet->buf;
                int mlen = packet->size - PRIMITIVE_BYTES;

                int err = crypto_decrypt(m, packet->buf, packet->size);
                if (err) {
                    goto error;
                }

                forward_to_target(target, m, mlen);

            } else if (rc == PACKET_INVALID) {
                goto error;
            }
        }

    } else if (nread < 0){
        close_source(source);
        close_target(target);
    }

    return;

error:
    logger_log(LOG_ERR, "invalid packet");
    close_source(source);
    close_target(target);
}
Пример #10
0
static void
remote_recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
    struct remote_context *remote;
    struct client_context *client;

    remote = stream->data;
    client = remote->client;

    if (nread > 0) {
        reset_timer(remote);
        struct packet *packet = &remote->packet;
        int rc = packet_filter(packet, buf->base, nread);
        if (rc == PACKET_COMPLETED) {
            uint8_t *m = packet->buf;
            int mlen = packet->size - PRIMITIVE_BYTES;

            int err = crypto_decrypt(m, packet->buf, packet->size);
            if (err) {
                goto error;
            }

            uv_read_stop(&remote->handle.stream);
            forward_to_client(client, m, mlen);

        } else if (rc == PACKET_INVALID) {
            goto error;
        }

    } else if (nread < 0){
        if (nread != UV_EOF) {
            logger_log(LOG_ERR, "receive from %s failed: %s", client->target_addr, uv_strerror(nread));
        }
        goto destroy;
    }

    return;

error:
    logger_log(LOG_ERR, "invalid tcp packet");
destroy:
    close_client(client);
    close_remote(remote);
}
Пример #11
0
int main()
{
    bytestring_t *key = bytestring_new_from_string("0123456789ABCDEFh");
    bytestring_t *ctx = bytestring_new(8);
    bytestring_t *src = bytestring_new_from_string("5468652071756663h");
    bytestring_t *dst = bytestring_new(8);
    bytestring_t *clr = bytestring_new(8);

    if (crypto_create_key(ctx,0,key)==CRYPTO_OK)
    {
        fprintf(stderr,"Create key succeeded\n");
    }
    else
    {
        fprintf(stderr,"Create key failed\n");
        return -3;
    }

    if (crypto_encrypt(dst,ctx,src,NULL)==CRYPTO_OK)
    {
        fprintf(stderr,"Crypto: %s\n",bytestring_to_alloc_string(dst));
    }
    else
        fprintf(stderr,"Crypto failed\n");

    if (crypto_decrypt(clr,ctx,dst,NULL)==CRYPTO_OK)
    {
        if (bytestring_is_equal(clr,src))
            fprintf(stderr,"Decrypted clear text matches initial text\n");
        else
            fprintf(stderr,"Crypto: %s\n",bytestring_to_alloc_string(clr));
    }
    else
        fprintf(stderr,"Crypto failed\n");

    return 0;
}
Пример #12
0
int
k5_ef_crypto(const char *in, char *out,
	long length, krb5_keyblock *key,
	const krb5_data *ivec, int encrypt_flag)
{
	int rv = CRYPTO_FAILED;

	crypto_mechanism_t mech;
	crypto_data_t d1, d2;

	ASSERT(in != NULL);
	ASSERT(out != NULL);
	ASSERT(key != NULL);
	ASSERT(key->contents != NULL);

	bzero(&d1, sizeof (d1));
	bzero(&d2, sizeof (d2));

	d1.cd_format = CRYPTO_DATA_RAW;
	d1.cd_offset = 0;
	d1.cd_length = length;
	d1.cd_raw.iov_base = (char *)in;
	d1.cd_raw.iov_len = length;

	d2.cd_format = CRYPTO_DATA_RAW;
	d2.cd_offset = 0;
	d2.cd_length = length;
	d2.cd_raw.iov_base = (char *)out;
	d2.cd_raw.iov_len = length;

	mech.cm_type = key->kef_mt;
	if (mech.cm_type == CRYPTO_MECH_INVALID) {
		KRB5_LOG(KRB5_ERR,
		    "k5_ef_crypto - invalid crypto mech type: 0x%llx",
		    (long long)key->kef_mt);
		return (CRYPTO_FAILED);
	}

	if (ivec != NULL) {
		mech.cm_param_len = ivec->length;
		mech.cm_param = (char *)ivec->data;
	} else {
		mech.cm_param_len = 0;
		mech.cm_param = NULL;
	}

	if (encrypt_flag)
		rv = crypto_encrypt(&mech, &d1,
				    &key->kef_key,
				    key->key_tmpl,
				    (in != out ? &d2 : NULL),
				    NULL);
	else
		rv = crypto_decrypt(&mech, &d1,
				    &key->kef_key,
				    key->key_tmpl,
				    (in != out ? &d2 : NULL),
				    NULL);

	if (rv != CRYPTO_SUCCESS) {
		KRB5_LOG1(KRB5_ERR,
			"k5_ef_crypto: %s error: rv = 0x%08x",
			(encrypt_flag ? "encrypt" : "decrypt"),
			rv);
		return (CRYPTO_FAILED);
	}

	return (0);
}
Пример #13
0
int run_vpn(shadowvpn_args_t *args) {
  fd_set readset;
  int tun, sock, max_fd;
  ssize_t r;
  unsigned char *tun_buf;
  unsigned char *udp_buf;
  struct sockaddr_storage remote_addr;
  struct sockaddr *remote_addrp = (struct sockaddr *)&remote_addr;
  socklen_t remote_addrlen;
  struct sockaddr *src_addrp = NULL;
  socklen_t *src_addrlen = NULL;

  if (args->mode == SHADOWVPN_MODE_SERVER) {
    // if we are running a server, update server address from recv_from
    src_addrp = remote_addrp;
    src_addrlen = &remote_addrlen;
  }

  if (-1 == (tun = tun_alloc(args->intf))) {
    errf("failed to create tun device");
    return -1;
  }
  if (-1 == (sock = udp_alloc(args->mode == SHADOWVPN_MODE_SERVER,
                              args->server, args->port,
                              remote_addrp, &remote_addrlen))) {
    errf("failed to create UDP socket");
    close(tun);
    return -1;
  }

  shell_up(args);

  tun_buf = malloc(args->mtu + SHADOWVPN_ZERO_BYTES);
  udp_buf = malloc(args->mtu + SHADOWVPN_ZERO_BYTES);
  memset(tun_buf, 0, SHADOWVPN_ZERO_BYTES);
  memset(udp_buf, 0, SHADOWVPN_ZERO_BYTES);

  for(;;) {
    FD_ZERO(&readset);
    FD_SET(tun, &readset);
    FD_SET(sock, &readset);
    max_fd = max(tun, sock) + 1;

    if (-1 == select(max_fd, &readset, NULL, NULL, NULL)) {
      if (errno == EINTR)
        continue;
      err("select");
      break;
    }
    if (FD_ISSET(tun, &readset)) {
      r = read(tun, tun_buf + SHADOWVPN_ZERO_BYTES, args->mtu); 
      if (r == -1) {
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
          // do nothing
        } else if (errno == EPERM || errno == EINTR) {
          // just log, do nothing
          err("read from tun");
        } else {
          err("read from tun");
          break;
        }
      }
      if (remote_addrlen) {
        crypto_encrypt(udp_buf, tun_buf, r);
        r = sendto(sock, udp_buf + SHADOWVPN_PACKET_OFFSET,
                   SHADOWVPN_OVERHEAD_LEN + r, 0,
                   remote_addrp, remote_addrlen);
        if (r == -1) {
          if (errno == EAGAIN || errno == EWOULDBLOCK) {
            // do nothing
          } else if (errno == ENETUNREACH || errno == ENETDOWN ||
                     errno == EPERM || errno == EINTR || errno == EMSGSIZE) {
            // just log, do nothing
            err("sendto");
          } else {
            err("sendto");
            // TODO rebuild socket
            break;
          }
        }
      }
    }
    if (FD_ISSET(sock, &readset)) {
      r = recvfrom(sock, udp_buf + SHADOWVPN_PACKET_OFFSET,
                   SHADOWVPN_OVERHEAD_LEN + args->mtu, 0,
                   src_addrp, src_addrlen);
      if (r == -1) {
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
          // do nothing
        } else if (errno == ENETUNREACH || errno == ENETDOWN ||
                    errno == EPERM || errno == EINTR) {
          // just log, do nothing
          err("recvfrom");
        } else {
          err("recvfrom");
          // TODO rebuild socket
          break;
        }
      }

      if (-1 == crypto_decrypt(tun_buf, udp_buf, r - SHADOWVPN_OVERHEAD_LEN)) {
        errf("invalid packet, drop");
      } else {
        if (-1 == write(tun, tun_buf + SHADOWVPN_ZERO_BYTES,
              r - SHADOWVPN_OVERHEAD_LEN)) {
          if (errno == EAGAIN || errno == EWOULDBLOCK) {
            // do nothing
          } else if (errno == EPERM || errno == EINTR || errno == EINVAL) {
            // just log, do nothing
            err("write to tun");
          } else {
            err("write to tun");
            break;
          }
        }
      }
    }
  }
  free(tun_buf);
  free(udp_buf);

  shell_down(args);

  close(tun);
  close(sock);
  return -1;
}
Пример #14
0
static void
server_recv_cb(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags) {
    if (nread > 0) {
        struct client_context *client = handle->data;
        reset_timer(client);

        int mlen = nread - PRIMITIVE_BYTES;
        uint8_t *m = (uint8_t *)buf->base;
        int rc = crypto_decrypt(m, (uint8_t *)buf->base, nread);
        if (rc) {
            logger_log(LOG_ERR, "invalid udp packet");
            goto err;
        }

        /*
         *
         * xsocks UDP Response
         * +------+----------+----------+----------+
         * | ATYP | DST.ADDR | DST.PORT |   DATA   |
         * +------+----------+----------+----------+
         * |  1   | Variable |    2     | Variable |
         * +------+----------+----------+----------+
         *
         */
        union {
            struct sockaddr addr;
            struct sockaddr_in addr4;
            struct sockaddr_in6 addr6;
        } dest_addr;
        if (m[0] == ATYP_IPV4) {
            dest_addr.addr4.sin_family = AF_INET;
            memcpy(&dest_addr.addr4.sin_addr, m + 1, 4);
            memcpy(&dest_addr.addr4.sin_port, m + 5, 2);

        } else {
            dest_addr.addr6.sin6_family = AF_INET6;
            memcpy(&dest_addr.addr6.sin6_addr, m + 1, 16);
            memcpy(&dest_addr.addr6.sin6_port, m + 17, 2);
        }

        int addrlen = m[0] == ATYP_IPV4 ? IPV4_HEADER_LEN : IPV6_HEADER_LEN;
        memmove(m, m + addrlen, mlen - addrlen);
        mlen -= addrlen;

        if (!client->bind_server) {
            uv_os_sock_t sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
            if (sock < 0) {
                logger_stderr("socket error: %s\n", strerror(errno));
            }
            int yes = 1;
            if (setsockopt(sock, SOL_IP, IP_TRANSPARENT, &yes, sizeof(int))) {
                logger_stderr("setsockop IP_TRANSPARENT error: %s)", strerror(errno));
            }

            client->dest_handle = malloc(sizeof(uv_udp_t));
            uv_udp_init(handle->loop, client->dest_handle);
            rc = uv_udp_open(client->dest_handle, sock);
            if (rc) {
                logger_stderr("udp open error: %s", uv_strerror(rc));
            }
            rc = uv_udp_bind(client->dest_handle, &dest_addr.addr, UV_UDP_REUSEADDR);
            if (rc) {
                logger_stderr("udp server bind error: %s", uv_strerror(rc));
            }

            client->bind_server = 1;
        }

        forward_to_client(client, m , mlen);

    } else {
        goto err;
    }

    return;

err:
    free(buf->base);
}
Пример #15
0
/*
 * zcrypt_unwrap_key
 *
 * Using the provided wrapping key unwrap the key into a zcrypt_key_t.
 *
 * Allocates a zcrypt_key_t using kmem_alloc(), caller should free
 * using zcrypt_key_free().
 *
 * returns 0 on success
 */
int
zcrypt_unwrap_key(zcrypt_key_t *wk, uint64_t crypt,
    caddr_t wkeybuf, size_t wkeylen, zcrypt_key_t **zck)
{
	crypto_mechanism_t wmech;
	crypto_data_t wkey_cdt, ptkey_cdt;
	zcrypt_key_t *tmpzck;
	caddr_t uwrapkey, uwrapmac;
	size_t uwrapkeylen, uwrapmaclen;
	size_t keylen;
	int ret;
	zcrypt_key_phys_t *wkeyphys = (zcrypt_key_phys_t *)wkeybuf;
	uint64_t wcrypt;

	ASSERT(wkeybuf != NULL);
	ASSERT(wkeylen != 0);

	/*
	 * We maybe unwrapping a key of a smaller length than the wrapping
	 * key so unwrapbuflen and keylen need to take that into account.
	 *
	 * The incoming wkey also has the iv stored at the start.
	 */
	wcrypt = wkeyphys->zkp_crypt;
	ASSERT3U(wcrypt, <, ZIO_CRYPT_WRAP_FUNCTIONS);

	wmech.cm_type = crypto_mech2id(
	    zio_crypt_wrap_table[wcrypt].cwi_mechname);
	if (wmech.cm_type == CRYPTO_MECH_INVALID) {
		return (EINVAL);
	}
	keylen = zio_crypt_table[crypt].ci_keylen;

	if (wcrypt == ZIO_CRYPT_WRAP_AES_CCM) {
		CK_AES_CCM_PARAMS *ccmp;
		ccmp = kmem_zalloc(sizeof (CK_AES_CCM_PARAMS), KM_SLEEP);
		ccmp->ulNonceSize = zio_crypt_wrap_table[wcrypt].cwi_ivlen;
		ccmp->nonce = (uchar_t *)wkeyphys->zkp_kiv;
		ccmp->ulMACSize = zio_crypt_wrap_table[wcrypt].cwi_maclen;
		ccmp->ulDataSize = keylen + ccmp->ulMACSize;
		wmech.cm_param = (char *)ccmp;
		wmech.cm_param_len = sizeof (CK_AES_CCM_PARAMS);
	} else if (wcrypt == ZIO_CRYPT_WRAP_AES_GCM) {
		CK_AES_GCM_PARAMS *gcmp;
		gcmp = kmem_zalloc(sizeof (CK_AES_GCM_PARAMS), KM_SLEEP);
		gcmp->ulIvLen = zio_crypt_wrap_table[wcrypt].cwi_ivlen;
		gcmp->pIv = (uchar_t *)wkeyphys->zkp_kiv;
		gcmp->ulTagBits = zio_crypt_wrap_table[wcrypt].cwi_maclen * 8;
		wmech.cm_param = (char *)gcmp;
		wmech.cm_param_len = sizeof (CK_AES_GCM_PARAMS);
	} else {
		ASSERT(0);
	}

	uwrapkeylen = keylen + zio_crypt_wrap_table[wcrypt].cwi_maclen;
	uwrapkey = kmem_zalloc(uwrapkeylen, KM_SLEEP);

	SET_CRYPTO_DATA(ptkey_cdt, uwrapkey, uwrapkeylen);
	SET_CRYPTO_DATA(wkey_cdt, (char *)wkeyphys->zkp_key,
	    keylen + zio_crypt_wrap_table[wcrypt].cwi_maclen);

	ret = crypto_decrypt(&wmech, &wkey_cdt, &wk->zk_key,
	    NULL, &ptkey_cdt, NULL);
	kmem_free(wmech.cm_param, wmech.cm_param_len);
	if (ret != CRYPTO_SUCCESS) {
		kmem_free(uwrapkey, uwrapkeylen);
		zck = NULL;
		return (ret);
	}

	tmpzck = zcrypt_key_allocate();
	tmpzck->zk_key.ck_format = CRYPTO_KEY_RAW;
	tmpzck->zk_key.ck_data = kmem_alloc(keylen, KM_SLEEP);
	tmpzck->zk_key.ck_length = keylen * 8;
	tmpzck->zk_crypt = crypt;
	bcopy(uwrapkey, tmpzck->zk_key.ck_data, keylen);
	kmem_free(uwrapkey, uwrapkeylen);

	/* Now the HMAC-SHA256 key which we know is 32 bytes */
	keylen = 32;
	if (wcrypt == ZIO_CRYPT_WRAP_AES_CCM) {
		CK_AES_CCM_PARAMS *ccmp;
		ccmp = kmem_zalloc(sizeof (CK_AES_CCM_PARAMS), KM_SLEEP);
		ccmp->ulNonceSize = zio_crypt_wrap_table[wcrypt].cwi_ivlen;
		ccmp->nonce = (uchar_t *)wkeyphys->zkp_miv;
		ccmp->ulMACSize = zio_crypt_wrap_table[wcrypt].cwi_maclen;
		ccmp->ulDataSize = keylen + ccmp->ulMACSize;
		wmech.cm_param = (char *)ccmp;
		wmech.cm_param_len = sizeof (CK_AES_CCM_PARAMS);
	} else if (wcrypt == ZIO_CRYPT_WRAP_AES_GCM) {
		CK_AES_GCM_PARAMS *gcmp;
		gcmp = kmem_zalloc(sizeof (CK_AES_GCM_PARAMS), KM_SLEEP);
		gcmp->ulIvLen = zio_crypt_wrap_table[wcrypt].cwi_ivlen;
		gcmp->pIv = (uchar_t *)wkeyphys->zkp_miv;
		gcmp->ulTagBits = zio_crypt_wrap_table[wcrypt].cwi_maclen * 8;
		wmech.cm_param = (char *)gcmp;
		wmech.cm_param_len = sizeof (CK_AES_GCM_PARAMS);
	} else {
		ASSERT(0);
	}

	uwrapmaclen = keylen + zio_crypt_wrap_table[wcrypt].cwi_maclen;
	uwrapmac = kmem_zalloc(uwrapmaclen, KM_SLEEP);

	SET_CRYPTO_DATA(ptkey_cdt, uwrapmac, uwrapmaclen);
	SET_CRYPTO_DATA(wkey_cdt, (char *)wkeyphys->zkp_mackey,
	    keylen + zio_crypt_wrap_table[wcrypt].cwi_maclen);

	ret = crypto_decrypt(&wmech, &wkey_cdt, &wk->zk_key,
	    NULL, &ptkey_cdt, NULL);
	kmem_free(wmech.cm_param, wmech.cm_param_len);
	if (ret != CRYPTO_SUCCESS) {
		zcrypt_key_free(tmpzck);
		kmem_free(uwrapmac, uwrapmaclen);
		zck = NULL;
		return (ret);
	}

	tmpzck->zk_mackey.ck_format = CRYPTO_KEY_RAW;
	tmpzck->zk_mackey.ck_data = kmem_alloc(keylen, KM_SLEEP);
	tmpzck->zk_mackey.ck_length = keylen * 8;
	bcopy(uwrapmac, tmpzck->zk_mackey.ck_data, keylen);
	kmem_free(uwrapmac, uwrapmaclen);

	*zck = tmpzck;
	return (0);
}
Пример #16
0
static void
recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
    struct tundev_context *ctx;
    struct client_context *client;

    ctx = stream->data;
    client = container_of(stream, struct client_context, handle.stream);
    struct packet *packet = &client->packet;

    if (nread > 0) {

        if ((ctx->connect == AUTHING) &&
            ( (0 == memcmp(packet->buf, "GET ", 4)) || (0 == memcmp(packet->buf, "POST", 4)) )
            ) {
            http_auth(stream,  packet->buf);
            packet_reset(packet);
            ctx->connect = CONNECTED;
            return;
        }

        int rc = packet_filter(packet, buf->base, nread);
        if (rc == PACKET_UNCOMPLETE) {
            return;
        } else if (rc == PACKET_INVALID) {
            logger_log(LOG_ERR, "Filter Invalid: %d", nread);
            goto error;
        }

        int clen = packet->size;
        int mlen = packet->size - PRIMITIVE_BYTES;
        uint8_t *c = packet->buf, *m = packet->buf;

        assert(mlen > 0 && mlen <= ctx->tun->mtu);

        int err = crypto_decrypt(m, c, clen);
        if (err) {
            logger_log(LOG_ERR, "Fail Decrypt: %d", clen);
            goto error;
        }

        struct iphdr *iphdr = (struct iphdr *) m;

        in_addr_t client_network = iphdr->saddr & htonl(ctx->tun->netmask);
        if (client_network != ctx->tun->network) {
            char *a = inet_ntoa(*(struct in_addr *) &iphdr->saddr);
            logger_log(LOG_ERR, "Invalid client: %s", a);
            close_client(client);
            return;
        }

        if (client->peer == NULL) {
            uv_rwlock_rdlock(&rwlock);
            struct peer *peer = lookup_peer(iphdr->saddr, peers);
            uv_rwlock_rdunlock(&rwlock);
            if (peer == NULL) {
                char saddr[24] = {0}, daddr[24] = {0};
                parse_addr(iphdr, saddr, daddr);
                logger_log(LOG_WARNING, "[TCP] Cache miss: %s -> %s",
                           saddr, daddr);

                uv_rwlock_wrlock(&rwlock);
                peer = save_peer(iphdr->saddr, &client->addr, peers);
                uv_rwlock_wrunlock(&rwlock);

            } else {
                if (peer->data) {
                    struct client_context *old = peer->data;
                    close_client(old);
                }
            }

            peer->protocol= xTUN_TCP;
            peer->data = client;
            client->peer = peer;
        }

        network_to_tun(ctx->tunfd, m, mlen);

        packet_reset(packet);

    } else if (nread < 0) {
        if (nread != UV_EOF) {
            logger_log(LOG_ERR, "Receive from client failed: %s",
                       uv_strerror(nread));
        }
        close_client(client);
    }

    return;

error:
    if (verbose) {
        dump_hex(buf->base, nread, "Invalid tcp Packet");
    }
    handle_invalid_packet(client);
}