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