Exemplo n.º 1
0
int
example_syscall(struct credential *cred, int index, int op)
{
	struct object *o;
	int error = get_object(index, &o);
	if (error != 0)
		return (error);

	des_cblock		des_key;
	des_key_schedule	key_schedule;

	crypto_setup(&des_key, &key_schedule);

	if ((error = security_check(cred, o, op))) return error;
	some_helper(op);
	void_helper(o);
	perform_operation(op, o);

	crypto_encrypt(&des_key, &key_schedule);

	log_audit_record(o, op);

	release(o);

	return 0;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
static void
client_recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
    struct client_context *client = stream->data;
    struct remote_context *remote = client->remote;
    int clen;

    if (nread > 0) {
        reset_timer(remote);
        uv_read_stop(&client->handle.stream);

        switch (client->stage) {
        case XSTAGE_HANDSHAKE:
            if (verify_methods(buf->base, nread)) {
                handshake(client);
            } else {
                logger_log(LOG_ERR, "invalid method packet");
                close_client(client);
                close_remote(remote);
            }

            break;

        case XSTAGE_REQUEST:
            if (verify_request(buf->base, nread)) {
                request_start(client, buf->base);
            } else {
                logger_log(LOG_ERR, "invalid request packet");
                close_client(client);
                close_remote(remote);
            }

            break;

        case XSTAGE_FORWARD:
            clen = nread + PRIMITIVE_BYTES;
            uint8_t *c = client->buf + HEADER_BYTES;
            int rc = crypto_encrypt(c, (uint8_t*)buf->base, nread);
            if (rc) {
                logger_log(LOG_ERR, "encrypt failed");
                close_client(client);
                close_remote(remote);
            }
            forward_to_remote(remote, c, clen);

            break;

        default:
            break;
        }

    } else if (nread < 0) {
        if (nread != UV_EOF) {
            char addrbuf[INET6_ADDRSTRLEN + 1] = {0};
            uint16_t port = ip_name(&client->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);
    }
}
Exemplo n.º 4
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);
        uv_read_stop(&remote->handle.stream);
        int clen = nread + PRIMITIVE_BYTES;
        uint8_t *c = remote->buf + HEADER_BYTES;
        int rc = crypto_encrypt(c, (uint8_t*)buf->base, nread);
        if (!rc) {
            forward_to_client(client, c, clen);
        } else {
            logger_log(LOG_ERR, "invalid tcp packet");
            close_client(client);
            close_remote(remote);
        }

    } else if (nread < 0){
        if (nread != UV_EOF) {
            logger_log(LOG_ERR, "receive from %s failed: %s", client->target_addr, uv_strerror(nread));
        }
        close_client(client);
        close_remote(remote);
    }
}
Exemplo n.º 5
0
static void
client_recv_cb(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags) {
    struct server_context *server = container_of(handle, struct server_context, udp);
    if (nread > 0) {
        char key[KEY_BYTES + 1] = {0};
        crypto_generickey((uint8_t *)key, sizeof(key) -1, (uint8_t*)addr, sizeof(*addr), NULL, 0);

        struct client_context *client = NULL;
        uv_mutex_lock(&mutex);
        cache_lookup(cache, key, (void *)&client);
        uv_mutex_unlock(&mutex);

        if (client == NULL) {
            client = new_client();
            client->addr = *addr;
            client->local_handle = handle;
            memcpy(client->key, key, sizeof(key));
            uv_timer_init(handle->loop, client->timer);
            uv_udp_init(handle->loop, &client->server_handle);
            client->server_handle.data = client;
            uv_udp_recv_start(&client->server_handle, server_alloc_cb, server_recv_cb);
            uv_mutex_lock(&mutex);
            cache_insert(cache, client->key, (void *)client);
            uv_mutex_unlock(&mutex);
        }

        int clen = nread + PRIMITIVE_BYTES + addrlen;
        int mlen = nread + addrlen;
        uint8_t *c = (uint8_t *)buf->base - PRIMITIVE_BYTES - addrlen;
        uint8_t *m = (uint8_t *)buf->base - addrlen;

        if (server->dest_addr->sa_family == AF_INET) {
            struct sockaddr_in *addr = (struct sockaddr_in *)server->dest_addr;
            m[0] = 1;
            memcpy(m + 1, &addr->sin_addr, 4);
            memcpy(m + 1 + 4, &addr->sin_port, 2);
        } else {
            struct sockaddr_in6 *addr = (struct sockaddr_in6 *)server->dest_addr;
            m[0] = 4;
            memcpy(m + 1, &addr->sin6_addr, 16);
            memcpy(m + 1 + 16, &addr->sin6_port, 2);
        }

        int rc = crypto_encrypt(c, m, mlen);
        if (!rc) {
            reset_timer(client);
            forward_to_server(server->server_addr, client, c, clen);
        }

    } else {
        goto error;
    }

    return;

error:
    free(buf->base - addrlen - PRIMITIVE_BYTES);
}
Exemplo n.º 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;
}
Exemplo n.º 7
0
int FMT_crypt_save_fp(FILE *outfp, byte_string_t bs, const char *password)
{
    byte_string_t K, W;

    byte_string_set(K, password);
    crypto_encrypt(W, bs, K);
    fprintf(outfp, "\nW:\n");
    mime_put(W, outfp);

    byte_string_clear(K);
    byte_string_clear(W);

    return 1;
}
Exemplo n.º 8
0
/*
 *
 * SOCKS5 UDP Request
 * +----+------+------+----------+----------+----------+
 * |RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |
 * +----+------+------+----------+----------+----------+
 * | 2  |  1   |  1   | Variable |    2     | Variable |
 * +----+------+------+----------+----------+----------+
 *
 */
static void
client_recv_cb(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags) {
    struct server_context *server = container_of(handle, struct server_context, udp);
    if (nread > 0) {
        uint8_t frag = buf->base[2];
        if (frag) {
            logger_log(LOG_ERR, "don't support udp dgram frag");
            goto err;
        }

        char key[KEY_BYTES + 1] = {0};
        crypto_generickey((uint8_t *)key, sizeof(key) -1, (uint8_t*)addr, sizeof(*addr), NULL, 0);

        struct client_context *client = NULL;
        uv_mutex_lock(&mutex);
        cache_lookup(cache, key, (void *)&client);
        uv_mutex_unlock(&mutex);

        if (client == NULL) {
            client = new_client();
            client->addr = *addr;
            client->local_handle = handle;
            memcpy(client->key, key, sizeof(key));
            uv_timer_init(handle->loop, client->timer);
            uv_udp_init(handle->loop, &client->server_handle);
            client->server_handle.data = client;
            uv_udp_recv_start(&client->server_handle, server_alloc_cb, server_recv_cb);
            uv_mutex_lock(&mutex);
            cache_insert(cache, client->key, (void *)client);
            uv_mutex_unlock(&mutex);
        }

        int clen = nread - 3 + PRIMITIVE_BYTES;
        uint8_t *c = (uint8_t *)buf->base - PRIMITIVE_BYTES;
        int rc = crypto_encrypt(c, (uint8_t*)buf->base + 3, nread - 3);
        if (!rc) {
            reset_timer(client);
            forward_to_server(server->server_addr, client, c, clen);
        }

    } else {
        goto err;
    }

    return;

err:
    free(buf->base - PRIMITIVE_BYTES);
}
Exemplo n.º 9
0
static void
poll_cb(uv_poll_t *watcher, int status, int events) {
    struct tundev *tun;
    struct tundev_context *ctx;
    uint8_t *tunbuf, *m;

    ctx = container_of(watcher, struct tundev_context, watcher);
    tun = ctx->tun;

    tunbuf = malloc(PRIMITIVE_BYTES + tun->mtu);
    m = tunbuf + PRIMITIVE_BYTES;

    int mlen = read(ctx->tunfd, m, tun->mtu);
    if (mlen <= 0) {
        logger_log(LOG_ERR, "tun read error");
        free(tunbuf);
        return;
    }

    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 Source Address: %s", a);
            free(tunbuf);
            return;
    }



    if (ctx->connect == CONNECTED) {
         crypto_encrypt(tunbuf, m, mlen);
         tun_to_tcp_server(ctx, tunbuf, PRIMITIVE_BYTES + mlen);

    } else {
           free(tunbuf);
           if (ctx->connect == DISCONNECTED) {
                  connect_to_server(ctx);
           }
     }


    
}
Exemplo n.º 10
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);
}
Exemplo n.º 11
0
void
special_test_blf (void)
{
  u_int8_t *akey = "0123456789ABCDEFF0E1D2C3B4A59687";
  u_int8_t *aiv = "FEDCBA9876543210";
  u_int8_t data[] = "7654321 Now is the time for \0\0\0"; /* len 29 */
  u_int8_t *acipher
    = "6B77B4D63006DEE605B156E27403979358DEB9E7154616D959F1652BD5FF92CCE7";
  u_int8_t key[16], cipher[32], iv[8];
  struct crypto_xf *xf;
  struct keystate *ks;
  enum cryptoerr err;
  int i;

  asc2bin (key, akey, strlen (akey));
  asc2bin (iv, aiv, strlen (aiv));
  asc2bin (cipher, acipher, 64);

  xf = crypto_get (BLOWFISH_CBC);
  printf ("Special Test-Case %s: ", xf->name);

  ks = crypto_init (xf, key, 16, &err);
  if (!ks)
    {
      printf ("FAILED (init %d)", err);
      goto fail;
    }

  crypto_init_iv (ks, iv, xf->blocksize);
  crypto_encrypt (ks, data, 32);

  for (i = 0; i < 32; i++)
    if (data[i] != cipher[i])
	break;
  if (i < 32)
    printf ("FAILED ");
  else
    printf ("OKAY ");

  free (ks);

fail:
  printf ("\n");
  return;
}
Exemplo n.º 12
0
static void
request_to_server(struct remote_context *remote) {
    static uint16_t portlen = 2;
    size_t buflen;
    char buf[260] = {0};
    struct client_context *client = remote->client;

    struct sockaddr *addr = &dest_addr;

    /*
     *
     * xsocks request
     * +------+----------+----------+
     * | ATYP | BND.ADDR | BND.PORT |
     * +------+----------+----------+
     * |  1   | Variable |    2     |
     * +------+----------+----------+
     *
     */
    if (addr->sa_family == AF_INET) {
        size_t in_addr_len = sizeof(struct in_addr);
        buflen = sizeof(struct xsocks_request) + in_addr_len + portlen;
        buf[0] = ATYP_IPV4;
        memcpy(buf + 1, &((struct sockaddr_in *)addr)->sin_addr, in_addr_len);
        memcpy(buf + 1 + in_addr_len, &((struct sockaddr_in *)addr)->sin_port, portlen);

    } else {
        size_t in6_addr_len = sizeof(struct in6_addr);
        buflen = sizeof(struct xsocks_request) + sizeof(struct in6_addr) + portlen;
        buf[0] = ATYP_IPV6;
        memcpy(buf + 1, &((struct sockaddr_in6 *)addr)->sin6_addr, in6_addr_len);
        memcpy(buf + 1 + in6_addr_len, &((struct sockaddr_in6 *)addr)->sin6_port, portlen);
    }

    int clen = buflen + PRIMITIVE_BYTES;
    uint8_t *c = client->buf + HEADER_BYTES;
    int rc = crypto_encrypt(c, (uint8_t*)buf, buflen);
    if (!rc) {
        forward_to_remote(remote, c, clen);
    }
}
Exemplo n.º 13
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;
}
Exemplo n.º 14
0
void measure(void)
{
    int i;
    int loop;

    for (loop = 0; loop < LOOPS; ++loop) {
        for (i = 0; i <= TIMINGS; ++i) {
            cycles[i] = cpucycles();
            crypto_encrypt_keypair(pk,sk);
        }
        for (i = 0; i < TIMINGS; ++i) cycles[i] = cycles[i + 1] - cycles[i];
        printentry(-1,"keypair_cycles",cycles,TIMINGS);

        for (mlen = 0; mlen <= MAXTEST_BYTES; mlen += 1 + mlen / 4) {
            randombytes(m,mlen);

            for (i = 0; i <= TIMINGS; ++i) {
                cycles[i] = cpucycles();
                bytes[i] = crypto_encrypt(c,&clen,m,mlen,pk);
                if (bytes[i] == 0) bytes[i] = clen;
            }
            for (i = 0; i < TIMINGS; ++i) cycles[i] = cycles[i + 1] - cycles[i];
            printentry(mlen,"cycles",cycles,TIMINGS);
            printentry(mlen,"bytes",bytes,TIMINGS);

            for (i = 0; i <= TIMINGS; ++i) {
                cycles[i] = cpucycles();
                bytes[i] = crypto_encrypt_open(t,&tlen,c,clen,sk);
                if (bytes[i] == 0) bytes[i] = tlen;
            }
            for (i = 0; i < TIMINGS; ++i) cycles[i] = cycles[i + 1] - cycles[i];
            printentry(mlen,"open_cycles",cycles,TIMINGS);
            printentry(mlen,"open_bytes",bytes,TIMINGS);
        }
    }
}
Exemplo n.º 15
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);
}
Exemplo n.º 16
0
static void
request_start(struct client_context *client, char *req_buf) {
    struct socks5_request *req = (struct socks5_request *)req_buf;
    struct remote_context *remote = client->remote;

    assert(remote->stage == XSTAGE_FORWARD);

    client->cmd = req->cmd;

    if (req->cmd != S5_CMD_CONNECT && req->cmd != S5_CMD_UDP_ASSOCIATE) {
        logger_log(LOG_ERR, "unsupported cmd: 0x%02x", req->cmd);
        request_ack(client, S5_REP_CMD_NOT_SUPPORTED);
        return;
    }

    if (req->cmd == S5_CMD_UDP_ASSOCIATE) {
        request_ack(client, S5_REP_SUCCESSED);
        return;
    }

    char buf[260] = {0};
    size_t buflen;
    uint16_t portlen = 2;

    /*
     *
     * xsocks request
     * +------+----------+----------+
     * | ATYP | BND.ADDR | BND.PORT |
     * +------+----------+----------+
     * |  1   | Variable |    2     |
     * +------+----------+----------+
     *
     */
    if (req->atyp == ATYP_IPV4) {
        size_t in_addr_len = sizeof(struct in_addr);
        buflen = sizeof(struct xsocks_request) + in_addr_len + portlen;
        buf[0] = ATYP_IPV4;
        memcpy(buf + 1, req->addr, in_addr_len);
        memcpy(buf + 1 + in_addr_len, req->addr + in_addr_len, portlen);

        uv_inet_ntop(AF_INET, (const void *)(req->addr), client->target_addr, INET_ADDRSTRLEN);
        uint16_t port = read_size((uint8_t*)(req->addr + in_addr_len));
        sprintf(client->target_addr, "%s:%u", client->target_addr, port);

    } else if (req->atyp == ATYP_HOST) {
        uint8_t namelen = *(uint8_t *)(req->addr);
        if (namelen > 0xFF) {
            logger_log(LOG_ERR, "unsupported address type: 0x%02x", req->atyp);
            request_ack(client, S5_REP_ADDRESS_TYPE_NOT_SUPPORTED);
            return;
        }
        buflen = sizeof(struct xsocks_request) + 1 + namelen + portlen;
        buf[0] = ATYP_HOST;
        memcpy(buf + 1, req->addr, 1 + namelen);
        memcpy(buf + 1 + 1 + namelen, req->addr + 1 + namelen, portlen);

        memcpy(client->target_addr, req->addr + 1, namelen);
        uint16_t port = read_size((uint8_t*)(req->addr + 1 + namelen));
        sprintf(client->target_addr, "%s:%u", client->target_addr, port);

    } else if (req->atyp == ATYP_IPV6) {
        size_t in6_addr_len = sizeof(struct in6_addr);
        buflen = sizeof(struct xsocks_request) + in6_addr_len + portlen;
        buf[0] = ATYP_IPV6;
        memcpy(buf + 1, req->addr, in6_addr_len);
        memcpy(buf + 1 + in6_addr_len, req->addr + in6_addr_len, portlen);

        uv_inet_ntop(AF_INET6, (const void *)(req->addr), client->target_addr, INET_ADDRSTRLEN);
        uint16_t port = read_size((uint8_t*)(req->addr + in6_addr_len));
        sprintf(client->target_addr, "%s:%u", client->target_addr, port);

    } else {
        logger_log(LOG_ERR, "unsupported address type: 0x%02x", req->atyp);
        request_ack(client, S5_REP_ADDRESS_TYPE_NOT_SUPPORTED);
        return;
    }

    request_ack(client, S5_REP_SUCCESSED);

    // TODO: handle UDP ASSOCIATE
    if (req->cmd == S5_CMD_CONNECT) {
        if (verbose) {
            logger_log(LOG_INFO, "connect to %s", client->target_addr);
        }
        int clen = buflen + PRIMITIVE_BYTES;
        uint8_t *c = client->buf + HEADER_BYTES;
        int rc = crypto_encrypt(c, (uint8_t *)buf, buflen);
        if (!rc) {
            forward_to_remote(remote, c, clen);
        }
    }
}
Exemplo n.º 17
0
/*
 * zcrypt_wrap_key
 *
 * Using the provided wrapping key wrap the in memory representation of the
 * key into a form suitable for storage in a zap object.
 *
 * Uses kmem_alloc to create space for the wrapped key, the caller
 * should free with kmem_free when it is finished with the wrapped key.
 *
 * returns 0 on success
 */
int
zcrypt_wrap_key(zcrypt_key_t *wrappingkey, zcrypt_key_t *ptkey,
	caddr_t *wkeybuf, size_t *wkeylen, uint64_t wcrypt)
{
	crypto_mechanism_t wmech;
	crypto_data_t wkey_cdt, ptkey_cdt;
	size_t ptkeylen;
	size_t ivlen;
	int ret;
	zcrypt_key_phys_t *wkeyphys;

	/*
	 * Currently we only support wrapping keys of CRYPTO_KEY_RAW
	 */
	ASSERT(ptkey->zk_key.ck_format == CRYPTO_KEY_RAW);
	ASSERT(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);
	wkeyphys = kmem_zalloc(sizeof (zcrypt_key_phys_t), KM_PUSHPAGE); //Sleep
	wkeyphys->zkp_crypt = wcrypt;

	/*
	 * The data encryption and MAC keys are wrapped separately
	 * since in the future we may support one or both of them
	 * being in a FIPS 140-2 token as sensitive objects and we
	 * won't be able to treat them as "data" and wrap them together
	 * in one operation.
	 */

	/* Data encryption key is first */
	ptkeylen = CRYPTO_BITS2BYTES(ptkey->zk_key.ck_length);
	ivlen = zio_crypt_wrap_table[wcrypt].cwi_ivlen;
	VERIFY(random_get_bytes((uchar_t *)wkeyphys->zkp_kiv, ivlen) == 0);
	if (wcrypt == ZIO_CRYPT_WRAP_AES_CCM) {
		CK_AES_CCM_PARAMS *ccmp;
		ccmp = kmem_zalloc(sizeof (CK_AES_CCM_PARAMS), KM_PUSHPAGE); //Sleep
		ccmp->ulNonceSize = ivlen;
		ccmp->nonce = (uchar_t *)wkeyphys->zkp_kiv;
		ccmp->ulDataSize = ptkeylen;
		ccmp->ulMACSize = zio_crypt_wrap_table[wcrypt].cwi_maclen;
		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_PUSHPAGE); //Sleep
		gcmp->ulIvLen = 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);
	}

	SET_CRYPTO_DATA(wkey_cdt, (char *)wkeyphys->zkp_key,
	    ptkeylen + zio_crypt_wrap_table[wcrypt].cwi_maclen);
	SET_CRYPTO_DATA(ptkey_cdt, ptkey->zk_key.ck_data, ptkeylen);

#if _KERNEL
    printk("zcrypt 1\n");
#endif
	ret = crypto_encrypt(&wmech, &ptkey_cdt, &wrappingkey->zk_key,
	    NULL, &wkey_cdt, NULL);
	bzero(wmech.cm_param, wmech.cm_param_len);
	kmem_free(wmech.cm_param, wmech.cm_param_len);

	if (ret != CRYPTO_SUCCESS)
		goto out;

	/* Now the HMAC-SHA256 key for use with dedup IV generation */
	ptkeylen = CRYPTO_BITS2BYTES(ptkey->zk_mackey.ck_length);
	VERIFY(random_get_bytes((uchar_t *)wkeyphys->zkp_miv, ivlen) == 0);
	if (wcrypt == ZIO_CRYPT_WRAP_AES_CCM) {
		CK_AES_CCM_PARAMS *ccmp;
		ccmp = kmem_zalloc(sizeof (CK_AES_CCM_PARAMS), KM_PUSHPAGE); //Sleep
		ccmp->ulNonceSize = ivlen;
		ccmp->nonce = (uchar_t *)wkeyphys->zkp_miv;
		ccmp->ulDataSize = ptkeylen;
		ccmp->ulMACSize = zio_crypt_wrap_table[wcrypt].cwi_maclen;
		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_PUSHPAGE); //Sleep
		gcmp->ulIvLen = 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);
	}

	SET_CRYPTO_DATA(wkey_cdt, (char *)wkeyphys->zkp_mackey,
	    ptkeylen + zio_crypt_wrap_table[wcrypt].cwi_maclen);
	SET_CRYPTO_DATA(ptkey_cdt, ptkey->zk_mackey.ck_data, ptkeylen);

#if _KERNEL
    printk("zcrypt 2\n");
#endif
	ret = crypto_encrypt(&wmech, &ptkey_cdt, &wrappingkey->zk_key,
	    NULL, &wkey_cdt, NULL);

	bzero(wmech.cm_param, wmech.cm_param_len);
	kmem_free(wmech.cm_param, wmech.cm_param_len);
out:
	if (ret != CRYPTO_SUCCESS) {
		kmem_free(wkeyphys, sizeof (zcrypt_key_phys_t));
		*wkeylen = 0;
		return (ret);
	}

	*wkeylen = sizeof (zcrypt_key_phys_t);
	*wkeybuf = (caddr_t)wkeyphys;

	return (0);
}
Exemplo n.º 18
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;
}
Exemplo n.º 19
0
static void
poll_cb(uv_poll_t *watcher, int status, int events) {
 	char buffer[1024] = {0};
    char control_buffer[64] = {0};
    struct iovec iov[1];
    struct msghdr msg;
    struct sockaddr client_addr;
    struct server_context *server = container_of(watcher, struct server_context, watcher);

    if (status >= 0) {
        msg.msg_name = &client_addr;
        msg.msg_namelen = sizeof(client_addr);
        msg.msg_control = control_buffer;
        msg.msg_controllen = sizeof(control_buffer);
        iov[0].iov_base = buffer;
        iov[0].iov_len = sizeof(buffer);
        msg.msg_iov = iov;
        msg.msg_iovlen = 1;

        int msglen = recvmsg(watcher->io_watcher.fd, &msg, 0);
        if (msglen <= 0) {
            logger_stderr("receive from client error: %s", strerror(errno));
        }

        struct sockaddr dest_addr;
        if (getdestaddr(&msg, &dest_addr)) {
            logger_stderr("can not get destination address");
        }

        int addrlen = dest_addr.sa_family == AF_INET ? IPV4_HEADER_LEN : IPV6_HEADER_LEN;

        int mlen = addrlen + msglen;
        int clen = PRIMITIVE_BYTES + mlen;
        uint8_t *c = malloc(clen);
        uint8_t *m = c + PRIMITIVE_BYTES;

        /*
         *
         * xsocks UDP Request
         * +------+----------+----------+----------+
         * | ATYP | DST.ADDR | DST.PORT |   DATA   |
         * +------+----------+----------+----------+
         * |  1   | Variable |    2     | Variable |
         * +------+----------+----------+----------+
         *
         */
        if (dest_addr.sa_family == AF_INET) {
            struct sockaddr_in *addr = (struct sockaddr_in *)&dest_addr;
            m[0] = ATYP_IPV4;
            memcpy(m + 1, &addr->sin_addr, 4);
            memcpy(m + 1 + 4, &addr->sin_port, 2);

        } else {
            struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&dest_addr;
            m[0] = ATYP_IPV6;
            memcpy(m + 1, &addr->sin6_addr, 16);
            memcpy(m + 1 + 16, &addr->sin6_port, 2);
        }
        memcpy(m + addrlen, buffer, msglen);

        int rc = crypto_encrypt(c, m, mlen);
        if (!rc) {
            char key[KEY_BYTES + 1] = {0};
            crypto_generickey((uint8_t *)key, sizeof(key) -1, (uint8_t *)&client_addr, sizeof(client_addr), NULL, 0);

            struct client_context *client = NULL;
            uv_mutex_lock(&mutex);
            cache_lookup(cache, key, (void *)&client);
            uv_mutex_unlock(&mutex);
            if (client == NULL) {
                client = new_client();
                client->addr = client_addr;
                memcpy(client->key, key, sizeof(key));

                uv_timer_init(watcher->loop, client->timer);

                uv_udp_init(watcher->loop, &client->server_handle);
                client->server_handle.data = client;
                uv_udp_recv_start(&client->server_handle, server_alloc_cb, server_recv_cb);

                uv_mutex_lock(&mutex);
                cache_insert(cache, client->key, (void *)client);
                uv_mutex_unlock(&mutex);
            }

            reset_timer(client);
            forward_to_server(server->server_addr, client, c, clen);
        }
    }
}