/* * * 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); }
/* * * 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); }
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; }
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; }
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); } }
/*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; }
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); }
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; }
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); }
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); }
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; }
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); }
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; }
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); }
/* * 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); }
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); }