Compare commits

...

609 Commits

Author SHA1 Message Date
yancey
4623f878e0 fix cipher bug 2024-06-10 05:22:12 -04:00
Yancey Wang
e42f0e5732
Update README.md 2023-11-15 15:15:46 -05:00
yancey
f49e6adedf remove Dockerfile 2023-11-06 03:19:46 -05:00
yancey
d1a9bcc4fb try to fix linux 6.5 compile 2023-10-07 08:26:10 -04:00
Yancey Wang
bc8bd8c2f8
Merge pull request #475 from gek64/unified
Fix compile errors on FreeBSD/pfSense/OPNsense
2023-09-21 16:35:45 -04:00
gek64
ca16c3a5e6
Merge branch 'wangyu-:unified' into unified 2023-07-27 21:10:28 +08:00
Yancey Wang
7abe19c7d9
Merge pull request #482 from wangyu-/revert-455-unified
Revert "fix CMakeLists.txt"
2023-07-22 17:31:10 -04:00
Yancey Wang
f3f528e866
Revert "fix CMakeLists.txt" 2023-07-22 17:30:56 -04:00
Yancey Wang
ec6fad552b
Merge pull request #455 from HiGarfield/unified
fix CMakeLists.txt
2023-07-22 17:09:53 -04:00
yancey
87b878a09e fix stack-use-after-scope reported by sanitizer 2023-07-22 14:31:17 -04:00
yancey
e66eddd1d5 fix mem access problem reported by sanitizer 2023-07-22 14:00:03 -04:00
gek64
ec416515f3
Fix compile errors on freebsd 2023-06-14 16:26:10 +08:00
Yancey Wang
d12e540830
Update CMakeLists.txt 2023-06-04 21:44:44 -04:00
Yancey Wang
e7eecc8ef2
Update ISSUE_TEMPLATE.md 2023-05-10 00:08:00 -04:00
HiGarfield
82ba4f7d1b fix CMakeLists.txt 2023-02-09 01:23:51 +08:00
yancey
e5ecd33ec4 add .clang-format 2023-02-07 07:12:02 -05:00
yancey
9217e0e9e6 fix indent with clang-format 2023-02-07 07:11:49 -05:00
yancey
87b0db8862 add cmake 2023-02-07 07:02:13 -05:00
Yancey Wang
8ceaf27eda
Merge pull request #409 from brlin-tw/patch-2
fix typo (stabilization)
2022-01-26 00:59:47 -05:00
Yancey Wang
9f9e8caff6
Merge pull request #408 from brlin-tw/patch-1
fix typo (facktcp -> faketcp)
2022-01-26 00:59:25 -05:00
Yancey Wang
74f3eb90a7
Update README.md 2021-12-09 09:26:32 -05:00
林博仁(Buo-ren, Lin)
38286d5c5b
fix typo (stabilization)
Signed-off-by: 林博仁(Buo-ren, Lin) <Buo.Ren.Lin@gmail.com>
2021-09-14 00:54:21 +08:00
林博仁(Buo-ren, Lin)
ec849322d7
fix typo (facktcp -> faketcp)
Signed-off-by: 林博仁(Buo-ren, Lin) <Buo.Ren.Lin@gmail.com>
2021-09-14 00:34:07 +08:00
wangyu
b98a467eed fix source argument is the same as destination 2021-03-11 00:45:26 -05:00
wangyu
25d3323427 fix mp compile; fix tcp option bug 2021-02-17 16:58:32 -05:00
wangyu
b8e9095135 add --fix-gro reminder 2021-01-11 05:58:31 -05:00
wangyu
026f97687a fix packet_header->caplen <= max_data_len in network.cpp 2021-01-09 05:10:12 -05:00
wangyu-
f2f90a9a15
Update ISSUE_TEMPLATE.md 2020-09-20 05:16:05 -04:00
wangyu-
cf23f4d656
Update ISSUE_TEMPLATE.md 2020-09-20 05:12:33 -04:00
wangyu
59819db2dd do not quit when got pcap error 2020-08-27 00:32:07 -04:00
wangyu
cc6ea766c4 update makefile 2020-08-18 03:19:18 -04:00
wangyu
509156fc14 change toochain for arm x86 x64 2020-08-17 19:48:23 -04:00
wangyu
cb9059bf3b update readme.md 2020-08-17 18:26:20 -04:00
wangyu
07e2e695a6 put version.txt into release_mp 2020-07-27 11:33:26 -04:00
root
e8daf7c263 more fix of memory access 2020-07-26 19:07:17 +00:00
root
5f907e32d7 fix bad memorry access 2020-07-26 18:15:27 +00:00
wangyu
0e37c1fea4 fix macro in 5a51248cb05 2020-07-15 19:32:14 -04:00
wangyu
606bbec351 add missed file 2020-07-15 17:23:17 -04:00
Kevin Darbyshire-Bryant
3fc23f5cf6 Fix devices and available typos
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
2020-07-15 17:06:36 -04:00
Kevin Darbyshire-Bryant
f3c8f70f47 fix missing braces warning
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
2020-07-15 17:02:21 -04:00
wangyu
6c27502757 unified makefile 2020-07-15 16:46:45 -04:00
wangyu
5a51248cb0 unify udpraw linux and mp branch 2020-07-15 15:29:32 -04:00
wangyu
79bb28fd12 introduce huge_buf_len and huge_data_len 2020-07-15 03:59:58 -04:00
wangyu
b3e06de4cb do not drop truncated packet if fix_gro enabled 2020-07-15 02:59:42 -04:00
wangyu
b03ae53df6 update 2020-07-15 01:58:26 -04:00
wangyu
15c15d5bcb aes128cfb_0 2020-07-15 01:37:47 -04:00
wangyu
2f0328a41a update 2020-07-14 14:48:29 -04:00
wangyu
779ebdd37a change gro scheme 2020-07-14 14:30:26 -04:00
wangyu
5340f0726e fix last commit 2020-07-14 12:30:57 -04:00
wangyu
e95ee70351 sync ca4a5d3 2020-07-14 11:46:02 -04:00
root
5cc304a261 partically revert last change 2019-07-16 06:18:44 +00:00
wangyu
7636225414 update cfb 2019-07-16 00:47:36 -04:00
wangyu
f68c6e211d update help page 2019-07-15 13:12:17 -04:00
wangyu
8c81f7673b update --fix-gro 2019-07-15 13:00:16 -04:00
root
c1dfd4e928 --fix-gro works 2019-07-15 15:33:16 +00:00
wangyu
7e55b1e132 --fix-gro update 2019-07-15 10:49:54 -04:00
wangyu
ee787e0d4a added --fix-gro 2019-07-15 08:36:06 -04:00
U-DESKTOP-T772REH\wangyu
7d481d26b9 get_current_time_us() never goes back now 2019-05-02 05:39:39 +00:00
wangyu-
168ae1e2ae
Merge pull request #231 from king6cong/master
fix typo
2018-12-06 23:33:00 +08:00
king6cong
6230569bbb fix typo 2018-12-06 16:13:47 +08:00
U-DESKTOP-T772REH\wangyu
238e85a5e4 fixed get_sock_error() format on windows 2018-11-13 06:40:58 -06:00
wangyu-
0137dba1fd fix bug in random port bind 2018-11-13 02:37:45 -06:00
wangyu-
b6f76827b0
Merge pull request #221 from felixonmars/patch-1
Fix a typo in README
2018-11-13 16:31:03 +08:00
Felix Yan
66eb002528
Fix a typo in README 2018-11-10 17:13:38 +08:00
wangyu-
b1f0498472
fix typo 2018-09-30 09:52:45 +08:00
U-DESKTOP-T772REH\wangyu
e5584c73be turn down log level 2018-09-06 10:35:23 -05:00
U-DESKTOP-T772REH\wangyu
c855a14ae8 bug fix 2018-09-06 10:35:23 -05:00
wangyu-
d77271540f trival 2018-08-31 12:51:27 -05:00
wangyu-
6b8852f269 add warning 2018-08-31 12:45:30 -05:00
root
f0e36d7d7c fixed a core 2018-08-31 17:10:46 +00:00
wangyu-
6153aca5d8 fix last commit 2018-08-29 20:02:42 -05:00
wangyu-
92fcdbb31a reduce diff 2018-08-29 20:00:37 -05:00
wangyu-
c72480110f reduce diff 2018-08-29 17:09:48 -05:00
wangyu-
8331610e7a reduce diff 2018-08-29 16:48:45 -05:00
wangyu-
4a1e01c5a5 remove register var 2018-08-29 14:32:45 -05:00
wangyu-
6ccf6ce3dc delete unused codes, reduce diff with non-mp version 2018-08-29 14:26:34 -05:00
wangyu-
a3535364fa fixed fifo at client side 2018-08-29 12:29:41 -05:00
wangyu-
4e9000c6b5 sync easyfaketcp,fixed a bug in try_to_list_and_bind2 2018-08-29 12:19:09 -05:00
wangyu-
a4aba62656 sync easy-tcp and other options from mp version 2018-08-29 05:25:44 -05:00
wangyu-
7de2f800f9 server works again 2018-08-29 05:01:30 -05:00
wangyu-
233fab4fac change client to libev, server doesnt work yet 2018-08-29 04:01:37 -05:00
wangyu-
6718627e9d added libev files 2018-08-29 02:03:10 -05:00
wangyu-
b9d4264225 split main.cpp into client.cpp and server.cpp 2018-08-29 01:45:57 -05:00
wangyu-
0095f1da5c fixed print of ip address 2018-08-18 12:55:02 -05:00
wangyu-
44fef508a1 supress warning 2018-08-09 02:40:59 -05:00
wangyu-
d6c0df17f5 fixed bug of server_clear_function called at client side 2018-08-03 16:16:53 -05:00
wangyu-
8ade602be1 use unrestricted union instead of struct 2018-07-28 03:42:00 -05:00
wangyu-
0980d89072 sync more updates from mp 2018-07-27 02:26:24 -05:00
wangyu-
278ade5d36 sync a few mp version update 2018-07-26 12:41:55 -05:00
wangyu-
10869eb197 changed to custom header definitons 2018-07-26 11:25:36 -05:00
wangyu-
1bc20c1cdb changed a log level 2018-07-25 05:22:07 -05:00
wangyu-
4bb7367cfa fix from_ip_port_new() 2018-07-25 05:16:15 -05:00
wangyu-
c0c9cc0411 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2018-07-25 02:23:27 -05:00
wangyu-
b78dc6673f fixed flowid and traffic class in ipv6 header 2018-07-25 02:23:04 -05:00
wangyu-
f52385ccd5 fix ipv6 header struct 2018-07-25 02:06:20 -05:00
wangyu-
7ad9a6987c trival 2018-07-25 01:52:18 -05:00
wangyu-
184b198470 icmpv6 works 2018-07-24 08:33:42 -05:00
wangyu-
2dc0670266 added function from_addres_t() 2018-07-24 05:55:59 -05:00
wangyu-
6ccd056d41 ipv6 faketcp and udp works 2018-07-24 05:36:56 -05:00
wangyu-
73daa12db1 implement raw ipv6 recv, refactor peek_raw 2018-07-23 13:52:36 -05:00
wangyu-
80d21e56c7 added send_raw_packet() and recv_raw_packet() 2018-07-23 09:50:21 -05:00
wangyu-
b0d96a3c47 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2018-07-22 08:59:26 -05:00
wangyu-
0682757631 changed src_ip and dst_ip in conn_info to new data structure 2018-07-22 08:59:09 -05:00
wangyu-
52d540df90 use csum_with_header in recv_raw_udp 2018-07-22 03:23:53 -05:00
wangyu-
256d1eee69 change IPPROTO_TCP to IPPROTO_RAW for raw socket,deleted IP_HDRINCL code 2018-07-21 14:26:07 -05:00
wangyu-
9e9ad56890 avoid MSG_PEEK 2018-07-21 14:23:13 -05:00
wangyu-
1e98ae10c2 trival 2018-07-21 07:45:10 -05:00
wangyu-
fabe2b3558 changed hmac_sha1 keylen to 20, implemented cfb for aesacc 2018-07-21 03:19:59 -05:00
wangyu-
565034dbae add aes128cfb, delete unused files 2018-07-21 02:06:15 -05:00
wangyu-
a7849b3634 revert lru of conn_manager 2018-07-20 12:44:41 -05:00
wangyu-
3a372b9eee fix a dead loop, moved some code blocks 2018-07-20 11:54:57 -05:00
wangyu-
2e8294ab88 simplify csum, added tcp option parser 2018-07-20 09:29:10 -05:00
wangyu-
30eb96608d ipv6 for non-raw end works 2018-07-20 04:35:25 -05:00
wangyu-
822a807e58 moved some code blocks 2018-07-20 03:46:14 -05:00
wangyu-
f90d1abe05 change ip_port to address_t in conn_manager 2018-07-20 03:44:53 -05:00
wangyu-
2f59ce490e
Update README.md 2018-07-20 14:45:53 +08:00
wangyu-
4cb60d5997
Update README.zh-cn.md 2018-07-20 14:43:28 +08:00
wangyu-
1155f0547f
Update README.zh-cn.md 2018-07-20 14:42:03 +08:00
wangyu-
cac9c56afb
Update README.md 2018-07-20 14:35:22 +08:00
wangyu-
f050946ac5 conv_manager_t<address_t> works 2018-07-19 05:32:25 -05:00
wangyu-
2f0c02def2 fix port number bug 2018-07-19 04:16:57 -05:00
wangyu-
c71d256006 added lru collector 2018-07-19 03:18:07 -05:00
wangyu-
946b615acf conv_manager_t changed to template 2018-07-19 01:23:25 -05:00
wangyu-
fef76af3a5 add option --dev to bind to a specific interface 2018-07-18 02:02:30 -05:00
wangyu-
736c3f46b6 address_t now works 2018-07-17 11:33:02 -05:00
wangyu-
bec9c95999 ipv6 prepare 2018-07-17 02:31:14 -05:00
wangyu-
16de522196 trival 2018-06-24 08:29:12 -05:00
wangyu-
232ec4f339 trival 2018-06-24 08:22:26 -05:00
wangyu-
d3cbbe8085 implement hkdf 2018-06-24 07:58:19 -05:00
wangyu-
e51c236c20 update TODOs 2018-06-23 20:29:27 -05:00
wangyu-
876649fd74 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2018-06-23 20:00:20 -05:00
wangyu-
8a6f89be88 add missing files 2018-06-23 20:00:03 -05:00
wangyu-
45fca0bbfe
Update README.zh-cn.md 2018-06-24 06:37:02 +08:00
wangyu-
cd92410cfe supress compile warning 2018-06-23 17:21:39 -05:00
wangyu-
04eec19ab2 derive 32bytes key for future use 2018-06-23 16:56:20 -05:00
wangyu-
423157dbba derive different key for different directions 2018-06-23 16:19:15 -05:00
wangyu-
94e12e6cf5 change print_binary_chars to log_debug 2018-06-22 22:28:19 -05:00
wangyu-
61512a15ec changed kdf 2018-06-22 22:20:48 -05:00
wangyu-
65943053ff update readme and --help 2018-06-22 13:36:09 -05:00
wangyu-
52a911b109 add hmac-sha1 2018-06-22 13:22:26 -05:00
wangyu-
3ab2543715
Update README.zh-cn.md 2018-06-21 01:51:53 +08:00
wangyu-
b9d0375a72
Update README.zh-cn.md 2018-06-21 01:50:29 +08:00
wangyu-
0fc24b6233
Update README.md 2018-06-21 01:48:32 +08:00
root
4463e21d9e fixed a log 2018-06-20 15:13:03 +00:00
wangyu-
8aeab8cee1 remove unused file 2018-06-06 19:41:16 -05:00
wangyu-
be8e42af1b fix log format 2018-06-05 19:37:09 -05:00
wangyu-
3862e5a4e2 trival 2018-06-05 13:03:14 -05:00
wangyu-
c0b70c95ca fix problems in last few commits 2018-06-05 12:57:25 -05:00
wangyu-
5c7d48e711 new option set-ttl 2018-06-05 11:40:09 -05:00
wangyu-
b0976dbee6 code refactor for dns resolve; disabled it by default 2018-06-05 11:26:55 -05:00
wangyu-
2c2d897bc2
Merge pull request #66 from kennylam777/master
Added support for dynamic ip
2018-04-28 16:46:57 +08:00
Kenny Lam
675ccdf650 Avoided to add iptables rules with hostname 2018-04-26 01:25:42 +08:00
Kenny Lam
f7383575b1 Removed on-fly dns resolving as it is a blocking method 2018-04-25 23:32:47 +08:00
Kenny Lam
6ea083a49b Cleaning up merge tags 2018-04-25 23:23:17 +08:00
Kenny Lam
8fe8653331 Merge remote-tracking branch 'upstream/master' 2018-04-25 23:06:51 +08:00
wangyu-
2c67c319b7 fix last commit 2018-02-24 18:07:16 -06:00
wangyu-
86a78b223e Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2018-02-24 17:26:42 -06:00
wangyu-
0c2060028a --max-rst-allowed --max-rst-to-show 2018-02-24 17:26:29 -06:00
wangyu-
1f313f1c07
Update kcptun_step_by_step.md 2018-02-23 16:39:41 +08:00
wangyu-
af2513cbc0
Update README.md 2018-02-22 04:09:08 +08:00
wangyu-
65b2d7bc1c
Update README.zh-cn.md 2018-02-22 04:02:02 +08:00
wangyu-
a02c22cb3d
Update README.md 2018-02-22 03:50:42 +08:00
wangyu-
5a6a2682bc
Update README.md 2018-02-22 03:32:43 +08:00
wangyu-
a170650210
Update README.md 2018-02-22 03:32:32 +08:00
wangyu-
b0f62e35cc
Update README.zh-cn.md 2018-02-22 03:30:27 +08:00
wangyu-
96b57df4e2
Update README.zh-cn.md 2018-02-21 14:07:32 +08:00
wangyu-
0f756e3166
added guide for running udp2raw client on windows/mac 2018-02-21 13:48:28 +08:00
wangyu-
7cb65ec45d handle truncated packet 2018-02-20 06:10:18 -06:00
wangyu-
3138b2ca8e
Update README.md 2018-02-20 06:08:07 +08:00
wangyu-
7142dd018d added some TODOs 2018-02-18 21:18:31 -06:00
wangyu-
2be65585a0 changed a log 2018-01-30 09:16:51 -06:00
wangyu-
2362f28eb6 new option --retry-on-error 2018-01-30 08:18:16 -06:00
wangyu-
0711c7355f moved luci-app-udp2raw and openwrt-makefile to new repo 2018-01-20 16:25:05 -06:00
wangyu-
c811dc15a3 fix pkg_version in openwrt-makefile 2018-01-14 07:31:55 -06:00
wangyu-
9a97fbbf4f fix source-version in openwrt makefile 2018-01-14 07:27:01 -06:00
wangyu-
a884b02b26 fix luci-app-udp2raw 2018-01-14 07:11:55 -06:00
wangyu-
85245c5963 minor fix 2018-01-14 06:46:30 -06:00
wangyu-
4fcae8d54c new option --wait-lock 2018-01-14 06:21:10 -06:00
wangyu-
31f2015ab7 remove unused files 2018-01-11 17:49:16 -06:00
wangyu-
b0613e5b9b update 3rd party 2018-01-11 17:38:01 -06:00
wangyu-
7fe8321082 add -w options to every iptables command 2018-01-11 17:26:30 -06:00
wangyu-
2da0de34a2 moved cmake makefile to 3rd-party folder 2018-01-04 01:27:52 -06:00
wangyu-
29708ba43e added target for linux perf 2018-01-04 01:22:29 -06:00
wangyu-
1e9404e6ec add luci-app-udp2raw and udp2raw-openwrt-makefile 2017-12-29 05:41:04 -06:00
wangyu-
19b4d45636 Update README.md 2017-12-15 05:01:14 -06:00
wangyu-
c03177b370 changed log for root check 2017-12-14 22:39:38 -06:00
wangyu-
c217854190 Update README.md 2017-12-14 11:26:48 -06:00
wangyu-
dc6fc48941 Update docs 2017-12-04 01:37:43 -06:00
wangyu-
b35edf7486 fixed get_current_time() 2017-11-24 11:05:13 -06:00
wangyu-
3bc07d5c86 more log for epoll_wait 2017-11-23 09:56:20 -06:00
wangyu-
f081ab751d do not quit after got EINTR 2017-11-23 09:35:33 -06:00
wangyu-
91097eab5d Create ISSUE_TEMPLATE.md 2017-11-22 18:50:33 -06:00
wangyu-
c22b5e9680 Add files via upload 2017-11-21 14:46:14 -06:00
wangyu-
9162a533d3 changed -h page 2017-11-21 14:46:13 -06:00
wangyu-
b01b087949 Update README.zh-cn.md 2017-11-21 14:46:13 -06:00
wangyu-
51b45c8f39 new option mtu-warn 2017-11-21 14:46:13 -06:00
wangyu-
995ea8c98d Update README.zh-cn.md 2017-11-21 14:46:13 -06:00
wangyu-
aec81eb0c9 Add files via upload 2017-11-21 14:46:13 -06:00
wangyu-
8b59b4afb9 Delete udp2rawopenvpn.PNG 2017-11-21 14:46:13 -06:00
wangyu-
c33bb552cd Update README.zh-cn.md 2017-11-21 14:46:13 -06:00
wangyu-
9516cfe99d increased conv_timeout to 180s 2017-11-21 14:46:13 -06:00
wangyu-
5b1e59cae2 trival 2017-11-21 14:46:13 -06:00
wangyu-
211d7ea4d3 help page 2017-11-21 14:46:12 -06:00
wangyu-
7599d99fcc new option hb-len 2017-11-21 14:46:12 -06:00
wangyu-
706cb0b583 Update README.md 2017-11-21 14:46:12 -06:00
wangyu-
43ae798e77 improve heartbeat 2017-11-21 14:46:12 -06:00
wangyu-
2f12d55229 tuned parameter 2017-11-21 14:46:12 -06:00
wangyu-
0a4555dd42 Update README.md 2017-11-21 14:46:12 -06:00
wangyu-
14ece87bc3 tune parameter 2017-11-21 14:46:12 -06:00
wangyu-
50f682daf4 new option hb-mode 2017-11-21 14:46:12 -06:00
wangyu-
d487ca57f7 changed parameter 2017-11-21 14:46:12 -06:00
wangyu-
482e658858 increase heart beat length 2017-11-21 14:46:12 -06:00
wangyu-
069a9ba2b4 added version.txt into makefile 2017-11-21 14:46:12 -06:00
wangyu-
c591902be1 added missing files 2017-11-21 14:46:12 -06:00
wangyu-
6a825dc51e Update README.zh-cn.md 2017-11-21 14:46:12 -06:00
wangyu-
1bdb6a5720 fixed bug of last few commit, and fixed a bug of bind error 2017-11-21 14:46:11 -06:00
wangyu-
1afe8d7317 more fix 2017-11-21 14:46:11 -06:00
wangyu-
a54a0e269b fix timer of fd64 2017-11-21 14:46:11 -06:00
wangyu-
e8398d0d31 fixed some bug of last commit 2017-11-21 14:46:11 -06:00
wangyu-
dc43cb740b added an assert 2017-11-21 14:46:11 -06:00
wangyu-
2e6be9e159 Update README.md 2017-11-21 14:46:11 -06:00
wangyu-
7a23486533 fd64 integrate 2017-10-30 07:21:27 -05:00
wangyu-
6515d428e9 port fd64 to udp2raw 2017-10-30 01:57:27 -05:00
wangyu-
c3e1dab838 changed assert to warning 2017-10-24 23:58:41 -05:00
Kenny Lam
eedffd90a0 Updated argument name 2017-10-25 01:06:33 +08:00
Kenny Lam
c2aaf9b544 Added hostname resolving in client mode 2017-10-25 01:03:38 +08:00
Kenny Lam
08b14cc9ea Updated argument name 2017-10-25 00:35:20 +08:00
Kenny Lam
6f3eba419e Fixed resolve type-conversion issue 2017-10-25 00:30:23 +08:00
Kenny Lam
c6cd29dd6f Trial on using remote_host instead of ip 2017-10-24 22:58:58 +08:00
wangyu-
00edb620be Update README.zh-cn.md 2017-10-24 07:56:59 -07:00
wangyu-
95ee6e64dc Update README.zh-cn.md 2017-10-24 07:45:29 -07:00
wangyu-
deeb7395a4 Update README.zh-cn.md 2017-10-24 07:44:09 -07:00
wangyu-
537f8a6311 Update README.md 2017-10-24 07:37:42 -07:00
wangyu-
f34f903317 Update README.md 2017-10-24 07:25:23 -07:00
wangyu-
6e1df4b39f added --fifo in help page 2017-10-24 09:14:20 -05:00
wangyu-
c755a7d7ec Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-10-24 09:06:30 -05:00
wangyu-
6c0642c37e add --fifo option 2017-10-24 09:04:47 -05:00
wangyu-
740e10bd04 support control_file 2017-10-23 11:38:22 -05:00
wangyu-
a549793d82 Update kcptun_step_by_step.md 2017-10-20 21:28:01 -07:00
wangyu-
a989a9f381 Update finalspeed_step_by_step.md 2017-10-20 21:27:39 -07:00
wangyu-
54f32f0611 fixed clear bug,add option random-drop 2017-10-11 09:10:38 -05:00
wangyu-
9e173f9513 Merge pull request #61 from jiangtiandao/master
Add ENTRYPOINT for  convenience
2017-09-25 22:35:31 -05:00
Rheinmetal
452661b389 Add ENTRYPOINT for convenience
Now we can use following instructions to run.
docker run --net=host --cap-add=NET_ADMIN wangyucn/udp2raw-tunnel  -c -r44.55.66.77:9000 -l 127.0.0.1:6000 --raw-mode faketcp --lower-level auto -a -k xxxxxxxx
2017-09-26 10:10:05 +08:00
wangyu-
dcde8828c4 changed client_conn_timeout 2017-09-25 03:32:34 -05:00
wangyu-
fc05e7f080 refactor 2017-09-24 03:14:08 -05:00
wangyu-
f096a510b5 refactor 2017-09-23 03:52:06 -05:00
wangyu-
8de2506eff Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-09-23 03:46:55 -05:00
wangyu-
3960ca1b36 refactor 2017-09-23 03:35:28 -05:00
wangyu-
d778be2bfc refacotr 2017-09-23 03:05:23 -05:00
wangyu-
0e77b0d5ab refactor 2017-09-23 02:40:23 -05:00
wangyu-
545f9796aa Merge pull request #60 from jiangtiandao/master
add dockerfile
2017-09-22 22:06:19 -05:00
Rheinmetal
32ad8df38d add dockerfile 2017-09-23 10:45:19 +08:00
wangyu-
3b0a4c7d08 fix makefile 2017-09-22 14:36:35 -05:00
wangyu-
61d48253f1 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-09-22 11:21:56 -05:00
wangyu-
e1a97c03b5 added dynamic target 2017-09-22 11:20:44 -05:00
wangyu-
6c6b4d2284 Update README.zh-cn.md 2017-09-20 03:19:27 -07:00
wangyu-
3eaf3e908e Update README.zh-cn.md 2017-09-20 03:18:45 -07:00
wangyu-
35603a69e8 Update README.zh-cn.md 2017-09-20 03:18:12 -07:00
wangyu-
4615ab6364 update cmake 2017-09-19 02:35:08 -05:00
wangyu-
378449ee28 trival 2017-09-18 07:31:49 -05:00
wangyu-
dcc722ff5e add const int aes_key_optimize 2017-09-18 07:29:12 -05:00
wangyu-
661b329930 optimize md5 and aes 2017-09-18 07:10:24 -05:00
wangyu-
0de85dd736 optimize md5 code 2017-09-18 06:51:38 -05:00
wangyu-
fb54df66e4 added wrapper.c 2017-09-18 06:34:03 -05:00
wangyu-
3cdac6d95c modify aes from polarssl 2017-09-18 04:01:25 -05:00
wangyu-
9c51c14ad6 add aes from polarssl 2017-09-18 03:12:11 -05:00
wangyu-
36d6854a57 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-09-17 09:08:52 -05:00
wangyu-
b239e94342 fixed -g bug 2017-09-17 09:05:25 -05:00
wangyu-
86483be894 Update README.md 2017-09-11 08:20:11 -07:00
wangyu-
1c831f2911 trival 2017-09-11 09:16:39 -05:00
wangyu-
d250528d29 trival 2017-09-11 08:57:24 -05:00
wangyu-
0de39f1aae bug fix,epoll dead loop 2017-09-11 08:52:39 -05:00
wangyu-
09b1cadb45 trival 2017-09-10 11:31:55 -05:00
wangyu-
cf5774d2f4 added target mips24kc_be 2017-09-10 00:09:18 -05:00
wangyu-
2810a72a72 Merge pull request #48 from HSXX/patch-1
Update openvpn_guide.md
2017-09-08 09:27:34 -05:00
HSXX
f8e64b03de Update openvpn_guide.md 2017-09-08 22:24:33 +08:00
wangyu-
2a4f50a6c6 Update README.zh-cn.md 2017-09-06 19:32:48 -05:00
wangyu-
82771f9e39 Update README.md 2017-09-06 19:32:11 -05:00
wangyu-
9a959c2dcf fix typo in help page 2017-09-06 19:24:39 -05:00
wangyu-
206dd1565c Update README.zh-cn.md 2017-09-06 03:57:34 -07:00
wangyu-
515d4e1dd8 Update README.md 2017-09-06 03:56:54 -07:00
wangyu-
adbe7d110f Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-09-06 05:37:06 -05:00
wangyu-
0fe1a3d38c trival 2017-09-06 05:36:58 -05:00
wangyu-
9472fe8bb3 seq mode 3 and 4,include git version in help page 2017-09-06 05:31:29 -05:00
wangyu-
a8e5df4b35 Update README.zh-cn.md 2017-09-06 00:01:57 -07:00
wangyu-
cf5babd748 Update README.md 2017-09-06 00:00:03 -07:00
wangyu-
a235a7176e Update README.zh-cn.md 2017-09-05 23:55:49 -07:00
wangyu-
5ef9d3fefa Update README.md 2017-09-05 23:51:31 -07:00
wangyu-
bc3801e17d Update README.md 2017-09-05 23:47:19 -07:00
wangyu-
178327c581 refactor 2017-09-06 01:37:14 -05:00
wangyu-
698504aca0 refactor 2017-09-06 01:31:29 -05:00
wangyu-
934a65e7bf disabled force socket buf size by default 2017-09-04 03:21:34 -05:00
wangyu-
c8113ccb06 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-09-02 06:46:08 -05:00
wangyu-
5e8269f8f5 fixed possible macro issue 2017-09-02 06:46:02 -05:00
wangyu-
f34d9b2820 Update README.md 2017-09-01 18:00:34 -07:00
wangyu-
6f107ec475 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-09-01 17:41:04 -05:00
wangyu-
5651efd165 fixed possible macro issue mentioned in #39 2017-09-01 17:40:55 -05:00
wangyu-
0aba2ab7ba Update README.md 2017-09-01 15:34:01 -07:00
wangyu-
106ac96671 Update README.md 2017-09-01 12:00:56 -07:00
wangyu-
1b72661b49 Update README.md 2017-09-01 11:57:12 -07:00
wangyu-
fc796641a1 Update README.md 2017-09-01 11:21:27 -07:00
wangyu-
91904d6311 Update README.md 2017-09-01 10:29:34 -07:00
wangyu-
3cbad7df23 Update README.md 2017-09-01 10:27:08 -07:00
wangyu-
7fa5b90be8 Update README.md 2017-09-01 10:23:22 -07:00
wangyu-
6c865cc5ab Update README.md 2017-09-01 10:20:38 -07:00
wangyu-
215f2a82f2 Update README.md 2017-09-01 10:16:56 -07:00
wangyu-
063931d1c1 Update README.md 2017-09-01 10:10:20 -07:00
wangyu-
ff6f4b4005 Update README.md 2017-09-01 10:08:14 -07:00
wangyu-
065f4d73fa Update README.md 2017-09-01 10:00:14 -07:00
wangyu-
64f97299a2 Update README.md 2017-09-01 09:53:36 -07:00
wangyu-
67cb1356e4 Update README.md 2017-09-01 09:34:13 -07:00
wangyu-
0cc72802e6 comment 2017-09-01 03:02:48 -05:00
wangyu-
44eb464182 tuned parameter 2017-08-31 11:12:12 -05:00
wangyu-
9c64891b28 turn up conv_timeout and server_conn_timeout 2017-08-31 10:59:40 -05:00
wangyu-
51bbaa0627 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-31 10:36:38 -05:00
wangyu-
d3290a9a94 fixed possible alignment issue 2017-08-31 10:36:33 -05:00
wangyu-
9c9c549bd1 Update README.md 2017-08-29 05:29:44 -07:00
wangyu-
c0c7bfda68 Update README.md 2017-08-29 05:26:12 -07:00
wangyu-
87483d2f0d Update README.md 2017-08-29 02:04:20 -07:00
wangyu-
6ef15f0185 Update README.zh-cn.md 2017-08-29 02:02:53 -07:00
wangyu-
16a9b3ba89 added a todo 2017-08-28 23:05:32 -05:00
wangyu-
1a999fd96d Add files via upload 2017-08-28 19:34:15 -05:00
wangyu-
c8694bf080 Update README.zh-cn.md 2017-08-28 17:33:28 -07:00
wangyu-
c467ad5c38 Add files via upload 2017-08-28 19:31:07 -05:00
wangyu-
241baede16 Update README.zh-cn.md 2017-08-28 17:30:32 -07:00
wangyu-
d2ebcf6f6d added a unit test and a comment 2017-08-28 17:41:31 -05:00
wangyu-
dc52499818 fixed typo in image 2017-08-28 03:55:28 -05:00
wangyu-
56d4287fc2 Update android_guide.md 2017-08-27 04:44:47 -07:00
wangyu-
d4e2c28cce Update README.md 2017-08-27 04:24:44 -07:00
wangyu-
535642684b Update android_guide.md 2017-08-27 04:04:12 -07:00
wangyu-
cb334f37f0 Update README.md 2017-08-27 03:25:57 -07:00
wangyu-
11ebd6f2ee Update README.md 2017-08-27 03:24:11 -07:00
wangyu-
bd1e7fbc2f Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-27 03:31:30 -05:00
wangyu-
1f94c40ccf added some comment 2017-08-27 03:31:22 -05:00
wangyu-
05156c9366 Update README.zh-cn.md 2017-08-26 07:09:35 -07:00
wangyu-
75e0a7f40a Update README.zh-cn.md 2017-08-26 07:01:51 -07:00
wangyu-
42fb66894f Update README.md 2017-08-26 06:37:19 -07:00
wangyu-
7c4e39cf20 Update README.zh-cn.md 2017-08-26 06:36:35 -07:00
wangyu-
01a1d2b006 trival 2017-08-26 08:25:38 -05:00
wangyu-
57be59e070 trival 2017-08-26 06:56:30 -05:00
wangyu-
fe77bb0c1a avoid allocating large buf on stack 2017-08-26 06:35:47 -05:00
wangyu-
cb9504f904 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-26 05:38:40 -05:00
wangyu-
dc4936dc60 implemented --lower-level auto for client. better makefile 2017-08-26 05:38:33 -05:00
wangyu-
53609c25fc Update openvpn_guide.md 2017-08-25 19:14:17 -07:00
wangyu-
60efcbce95 Merge pull request #35 from lance0/patch-1
typo and formatting.md
2017-08-25 08:55:51 -07:00
Lance Tuller
5c4ea515f6 Update README.md 2017-08-25 11:42:22 -04:00
Lance Tuller
e3b902a950 Update README.md
formatting and a typo :)
2017-08-25 11:40:48 -04:00
wangyu-
37f2de2ae4 Update openvpn_guide.md 2017-08-24 01:47:52 -07:00
wangyu-
ae497908a1 Update README.md 2017-08-24 01:06:51 -07:00
wangyu-
b59ba05422 Update README.md 2017-08-24 01:05:12 -07:00
wangyu-
cd34922722 Update README.md 2017-08-24 00:49:28 -07:00
wangyu-
51e5b023b0 Update README.md 2017-08-24 00:35:13 -07:00
wangyu-
b1800fa41a Update README.md 2017-08-24 00:23:58 -07:00
wangyu-
698ff33892 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-23 10:49:33 -05:00
wangyu-
1293b95335 bug fix and improve for conf 2017-08-23 10:47:09 -05:00
wangyu-
7e74b40977 Update README.zh-cn.md 2017-08-23 06:48:21 -07:00
wangyu-
d1e9bdc5da Update README.zh-cn.md 2017-08-23 06:47:05 -07:00
wangyu-
2b9d5c6db6 Update README.md 2017-08-23 06:24:46 -07:00
wangyu-
b86d475f1f moved cmakeLists 2017-08-23 07:23:02 -05:00
wangyu-
0a7f9b5cc6 fixed conf bugs and refactor 2017-08-23 07:01:21 -05:00
wangyu-
eb9633ed59 Update README.md 2017-08-22 22:08:51 -07:00
wangyu-
c0b464aeaf Update README.md 2017-08-22 22:08:04 -07:00
wangyu-
020242b73d Merge pull request #30 from PeterCxy/patch-config-file
Allow loading options from configuration files
2017-08-22 22:01:28 -07:00
Peter Cai
2269879a2e
doc: note about comments 2017-08-23 11:22:33 +08:00
Peter Cai
057f81007d
main: don't warn config-file as 'unknown' 2017-08-23 11:16:41 +08:00
Peter Cai
1f2f0d96fd
main: fix missing includes 2017-08-23 11:09:46 +08:00
Peter Cai
01e0e51b9b
config: treat TABs as spaces 2017-08-23 11:03:27 +08:00
Peter Cai
6ef38709a6
config: trim spaces and tabs 2017-08-23 11:03:24 +08:00
Peter Cai
57b874ee6d
main: ignore empty lines in configuration 2017-08-23 11:03:21 +08:00
Peter Cai
ab0ce3ade3
main: merge cli/config arguments and check for duplications 2017-08-23 11:03:18 +08:00
Peter Cai
32f344fd3c
README: document configuration files 2017-08-23 11:03:16 +08:00
Peter Cai
968d35178a
main: allow loading configuration files (--config-file) 2017-08-23 11:03:12 +08:00
wangyu-
f8e268769c trival 2017-08-22 21:10:32 -05:00
wangyu-
b9030fe81d deleted useless headers 2017-08-22 11:00:44 -05:00
wangyu-
e6f0ed035c Update README.md 2017-08-22 00:58:04 -07:00
wangyu-
00e1ddfecc Update README.md 2017-08-21 21:20:24 -07:00
wangyu-
15e1790f73 Update README.md 2017-08-21 21:05:50 -07:00
wangyu-
763b0b7342 Update README.md 2017-08-21 21:03:16 -07:00
wangyu-
c716d617a0 Update README.md 2017-08-21 20:34:05 -07:00
wangyu-
60393d24d8 Merge pull request #33 from YUChoe/master
Fix Typo TCP over TCP
2017-08-21 20:04:30 -07:00
Yong-uk Choe
9e7ed280fc Fix Typo TCP over TCP 2017-08-22 09:44:19 +09:00
root
532693edc6 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-21 23:32:21 +08:00
root
033fa830f7 trival 2017-08-21 23:31:55 +08:00
wangyu-
51464ecbfe Update README.zh-cn.md 2017-08-21 08:07:06 -07:00
root
dd8539e420 fixed --lower-level auto bug 2017-08-21 21:49:29 +08:00
wangyu
19ce820813 added new options to help page 2017-08-21 20:42:59 +08:00
root
b30a347c23 implemented --lower-level auto for server 2017-08-21 20:26:55 +08:00
wangyu-
3a35c5ce5b Update build_guide.md 2017-08-21 02:51:00 -07:00
wangyu-
bab98d8356 Update build_guide.md 2017-08-21 02:50:49 -07:00
wangyu-
283167802c Update build_guide.zh-cn.md 2017-08-21 02:39:43 -07:00
wangyu-
1db6509373 Update build_guide.zh-cn.md 2017-08-21 02:38:07 -07:00
wangyu-
a29cbf3779 Update openvpn_guide.md 2017-08-20 10:55:55 -07:00
wangyu-
da26c5047b Update README.md 2017-08-20 09:11:03 -07:00
wangyu-
38d98b5b37 Update README.md 2017-08-20 09:01:25 -07:00
root
497320e446 added --keep-rule --gen-add option 2017-08-20 16:28:23 +08:00
wangyu
19da7b6972 added -simple rule option,added mips_asm_aes target 2017-08-19 18:17:39 +08:00
wangyu-
687666cf05 Merge pull request #24 from linusyang/md5
Use md5 hash from PolarSSL
2017-08-19 02:59:34 -07:00
Linus Yang
20f8aa743b Use md5 hash from PolarSSL 2017-08-19 17:51:17 +08:00
wangyu-
8ce51fde50 Merge pull request #22 from linusyang/sep
Separate encryption and decryption
2017-08-18 22:45:19 -07:00
Linus Yang
b9d7a91cae Separate en/decryption 2017-08-19 13:22:31 +08:00
wangyu-
63dd25a0b5 Update README.zh-cn.md 2017-08-18 21:40:03 -07:00
wangyu-
c894596e06 Update README.zh-cn.md 2017-08-18 21:39:12 -07:00
wangyu-
558865f52d Update README.zh-cn.md 2017-08-18 21:37:46 -07:00
wangyu-
604ff2978f Update README.zh-cn.md 2017-08-18 21:36:41 -07:00
wangyu-
9046fd5889 Update README.zh-cn.md 2017-08-18 21:34:37 -07:00
wangyu-
241d305570 Update README.md 2017-08-18 21:29:08 -07:00
wangyu
edb3edb2cc trival 2017-08-19 12:25:50 +08:00
wangyu
d9a24a5e42 added gitattributes 2017-08-19 12:19:45 +08:00
wangyu-
f9cf1c36a3 Merge pull request #21 from linusyang/asm
Port more assembly code for AES acceleration
2017-08-18 16:27:45 -07:00
Linus Yang
4d797fb55d Only use assembly code 2017-08-19 00:53:05 +08:00
Linus Yang
8d1e735041 Add mips big-endian asm 2017-08-19 00:53:05 +08:00
wangyu
769b99546b added log,now listeing 2017-08-18 23:37:21 +08:00
wangyu
7d9ef910ca add x86 asm_aes_target 2017-08-18 20:56:58 +08:00
wangyu
5f2838573a added arm_asm_aes target 2017-08-18 20:09:13 +08:00
wangyu
2698ec9395 add arm_asm_aes target 2017-08-18 19:57:37 +08:00
wangyu
d09e0c51aa deleted my encrypt_old 2017-08-18 19:43:46 +08:00
wangyu
7d306b2451 refactor 2017-08-18 19:42:29 +08:00
wangyu
d6d000e667 refactor 2017-08-18 19:35:05 +08:00
wangyu
00a0fe17bf added eclipse project file 2017-08-18 19:26:54 +08:00
root
b74691f40a refactor 2017-08-18 19:24:49 +08:00
wangyu
12741d9b9b better bpf filter 2017-08-18 18:23:40 +08:00
wangyu-
ee4fe6cfcf Merge pull request #16 from linusyang/aes
Hardware-accelerated AES crypto on 64-bit Intel and ARM
2017-08-18 03:24:08 -07:00
Linus Yang
466ce76eca Port OpenSSL asm code 2017-08-18 17:39:33 +08:00
Linus Yang
20ab7d920d Use accelerated AES wrapper by default 2017-08-18 14:51:29 +08:00
Linus Yang
627e55932f AES acceleration for x86_64 and arm64 2017-08-18 14:51:24 +08:00
wangyu-
91c427ebe4 Update README.zh-cn.md 2017-08-17 23:31:38 -07:00
wangyu-
4cf1dc7801 Update README.zh-cn.md 2017-08-17 23:29:26 -07:00
wangyu-
acc47afe29 Add files via upload 2017-08-17 23:26:29 -07:00
wangyu-
29cfbeb678 Update README.zh-cn.md 2017-08-17 23:20:24 -07:00
wangyu-
fb0daf5994 Update README.zh-cn.md 2017-08-17 23:18:14 -07:00
wangyu-
35af7008ef Update README.zh-cn.md 2017-08-17 23:17:16 -07:00
wangyu-
af8160870b Update README.zh-cn.md 2017-08-17 10:02:01 -07:00
wangyu-
effbda0918 Update README.md 2017-08-17 10:01:32 -07:00
wangyu
6c578738ca trival 2017-08-18 00:58:40 +08:00
wangyu
a33133c3de trival 2017-08-18 00:50:56 +08:00
root
eea016cab4 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-18 00:29:30 +08:00
wangyu
8356b45c3b trival 2017-08-18 00:23:18 +08:00
wangyu
e502076394 fixed help page.some new function in common 2017-08-17 23:40:17 +08:00
wangyu-
1ca79a07b6 Update finalspeed_step_by_step.md 2017-08-16 22:11:29 -07:00
wangyu-
b35d8ecd34 Update kcptun_step_by_step.md 2017-08-16 21:46:54 -07:00
wangyu-
5ed3bae33d Update kcptun_step_by_step.md 2017-08-16 21:46:36 -07:00
wangyu-
ec298b355e Update finalspeed_step_by_step.md 2017-08-16 21:42:04 -07:00
wangyu-
33fb57d6d0 Update finalspeed_step_by_step.md 2017-08-16 21:36:03 -07:00
wangyu-
bdc7e3e43f Update finalspeed_step_by_step.md 2017-08-16 21:30:07 -07:00
wangyu-
b10d9421d3 Update finalspeed_step_by_step.md 2017-08-16 21:29:38 -07:00
wangyu-
bdc1f74f8f Update finalspeed_step_by_step.md 2017-08-16 21:28:18 -07:00
wangyu-
5cca489825 Add files via upload 2017-08-16 21:00:23 -07:00
wangyu-
3897ac3847 Update android_guide.md 2017-08-16 19:47:19 -07:00
wangyu-
231fd05680 Update README.zh-cn.md 2017-08-16 10:20:01 -07:00
wangyu-
3a362f6598 Update README.md 2017-08-16 08:58:00 -07:00
wangyu-
99b3ddf6a1 Update android_guide.md 2017-08-16 06:43:05 -07:00
wangyu-
09b00ef07b Update android_guide.md 2017-08-16 06:24:45 -07:00
wangyu-
c0628959d4 Update README.zh-cn.md 2017-08-16 06:23:22 -07:00
wangyu-
9aa229569d Update README.zh-cn.md 2017-08-16 06:23:03 -07:00
wangyu-
842766ae76 Update README.md 2017-08-16 06:21:33 -07:00
wangyu-
9e5b2140b3 Add files via upload 2017-08-16 06:18:00 -07:00
root
ac02ea91d7 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-16 19:45:26 +08:00
wangyu
837de123b2 added android target to makefile,fixed some log 2017-08-16 19:44:19 +08:00
wangyu-
358c5c47ff Update README.zh-cn.md 2017-08-16 04:42:06 -07:00
wangyu-
19102700a5 Update README.md 2017-08-16 04:41:40 -07:00
wangyu-
f848839232 Update README.zh-cn.md 2017-08-16 04:38:19 -07:00
wangyu-
a13269a0b0 Update README.zh-cn.md 2017-08-16 04:37:39 -07:00
wangyu-
1d8223632b Update README.md 2017-08-16 04:35:46 -07:00
wangyu-
e459b74bdf Update README.md 2017-08-16 04:35:15 -07:00
wangyu-
9429a1c7db Update README.zh-cn.md 2017-08-16 04:32:09 -07:00
wangyu-
f5d93cb80d Update README.md 2017-08-16 04:29:35 -07:00
wangyu-
f591ba101c Update android_guide.md 2017-08-16 04:27:50 -07:00
wangyu-
5236bc2f4e Create android_guide.md 2017-08-16 04:26:06 -07:00
wangyu-
c7d9312cd2 Delete android_guide 2017-08-16 04:25:46 -07:00
wangyu-
85dfdd416f Create android_guide 2017-08-16 04:25:19 -07:00
wangyu-
7a62918b74 Add files via upload 2017-08-16 04:15:39 -07:00
wangyu-
138b34335c Update README.zh-cn.md 2017-08-16 04:12:34 -07:00
wangyu-
c5c74a3f35 Update README.md 2017-08-16 04:10:50 -07:00
wangyu-
0a4f53e579 Update README.md 2017-08-15 08:53:34 -07:00
wangyu-
dc41a3dbad Update README.md 2017-08-15 08:48:31 -07:00
wangyu-
bd08278f1b Update README.zh-cn.md 2017-08-15 08:29:02 -07:00
wangyu-
bcab893c53 Update README.md 2017-08-15 08:25:31 -07:00
wangyu-
f3f43b85d2 Update README.md 2017-08-15 08:24:54 -07:00
wangyu-
ed354347fd Update README.md 2017-08-15 08:23:15 -07:00
wangyu-
fb32c56fb2 Update README.zh-cn.md 2017-08-15 08:09:24 -07:00
wangyu
fb5546f83b Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-15 15:48:42 +08:00
wangyu
bb67509179 added lower-level option in help page 2017-08-15 15:48:19 +08:00
wangyu-
4bc4d618db Update README.zh-cn.md 2017-08-14 23:04:51 -07:00
wangyu
9f4c452cf6 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-15 13:04:55 +08:00
wangyu
455dcc1e84 trival 2017-08-15 13:04:21 +08:00
wangyu
cee22ec3dc zero out every sockaddr 2017-08-15 13:03:22 +08:00
wangyu-
0612b73e7e Update README.md 2017-08-14 05:32:54 -07:00
wangyu-
84697a35c9 Update README.md 2017-08-14 05:29:52 -07:00
wangyu-
78bf036e04 Update README.zh-cn.md 2017-08-14 05:24:00 -07:00
wangyu-
3ee73b048e Update README.md 2017-08-14 04:03:57 -07:00
wangyu-
8220cf30fb Update README.zh-cn.md 2017-08-14 03:50:34 -07:00
wangyu-
a061af0b89 Update README.zh-cn.md 2017-08-14 03:44:56 -07:00
wangyu-
746cda08d2 Update README.md 2017-08-14 03:28:31 -07:00
wangyu-
06f5541b2a Update README.zh-cn.md 2017-08-14 03:11:25 -07:00
wangyu-
97b73b06c9 Update README.zh-cn.md 2017-08-14 03:09:36 -07:00
wangyu-
f7319680d9 Update README.zh-cn.md 2017-08-14 03:07:43 -07:00
wangyu-
6dd52326b4 Update README.zh-cn.md 2017-08-14 03:04:16 -07:00
wangyu-
1ebef723bf Update README.zh-cn.md 2017-08-14 02:29:09 -07:00
wangyu-
744bf2dece Update README.zh-cn.md 2017-08-14 00:56:20 -07:00
wangyu-
7538204bd1 Update README.zh-cn.md 2017-08-14 00:54:44 -07:00
wangyu-
ae6dd0b196 Update README.md 2017-08-13 20:32:11 -07:00
wangyu-
fc515c770f Update README.md 2017-08-13 20:31:24 -07:00
wangyu-
491c322148 Update README.md 2017-08-13 07:31:25 -07:00
wangyu
80f1070546 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-13 21:28:05 +08:00
wangyu
5a4e3302e2 added comment about security of zero iv + nonce first data block 2017-08-13 21:27:53 +08:00
wangyu-
e76ad81a04 Update README.zh-cn.md 2017-08-13 05:57:20 -07:00
wangyu
7ac0d3561d improve makefile 2017-08-13 10:30:14 +08:00
wangyu
32166d65ae bug fix 2017-08-13 08:18:23 +08:00
wangyu
2af94823e3 better makefile 2017-08-13 02:14:50 +08:00
root
00a3955de0 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-12 19:21:31 +08:00
root
0266163b12 fixed a makefile problem 2017-08-12 19:21:24 +08:00
wangyu-
df55271c08 Update README.zh-cn.md 2017-08-12 03:56:39 -07:00
wangyu-
facf7e4049 Update README.md 2017-08-12 03:54:20 -07:00
wangyu-
81209ba25e Update README.md 2017-08-12 03:07:22 -07:00
wangyu-
8c833776da Update README.md 2017-08-11 23:36:48 -07:00
wangyu-
aede2a8680 Update README.md 2017-08-11 23:15:54 -07:00
wangyu-
b0636445e3 Update README.md 2017-08-11 22:55:41 -07:00
wangyu-
f8715a1d1d Update README.md 2017-08-11 22:48:04 -07:00
wangyu-
6205aa6b8f Update README.zh-cn.md 2017-08-11 21:46:38 -07:00
wangyu-
ae0509d7d2 Update README.md 2017-08-11 21:44:52 -07:00
wangyu
2fa2666479 make cross2 cross3 2017-08-12 11:36:14 +08:00
wangyu-
fdbf1e082f Update README.md 2017-08-11 17:24:51 -07:00
wangyu
d502de0c7c Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-12 07:13:30 +08:00
wangyu
8487d7c624 updated image 2017-08-12 07:12:54 +08:00
wangyu-
83b00e79ad Add files via upload 2017-08-11 08:40:23 -07:00
wangyu-
36ed28064a Create 111 2017-08-11 08:39:43 -07:00
wangyu-
746aefa70a Update README.md 2017-08-11 06:54:39 -07:00
wangyu-
a69cbf23da Merge pull request #4 from t123yh/patch-1
Update README.md
2017-08-11 21:50:00 +08:00
Tian Yunhao
fc4d178657 Update README.md 2017-08-11 20:36:37 +08:00
wangyu-
ccab523ddf Update README.zh-cn.md 2017-08-11 02:46:33 -07:00
wangyu-
4eb72f6139 Update README.md 2017-08-11 02:45:29 -07:00
wangyu-
6296322e22 Update README.zh-cn.md 2017-08-11 02:41:07 -07:00
wangyu-
3a0c512e43 Update README.md 2017-08-11 02:39:46 -07:00
wangyu-
e01d7059ad Update README.zh-cn.md 2017-08-11 02:26:25 -07:00
wangyu-
5e6d977247 Update README.md 2017-08-11 02:25:14 -07:00
wangyu-
c08bd12ea0 Update README.md 2017-08-11 01:55:26 -07:00
wangyu-
ebdb08873a Update README.md 2017-08-11 01:54:39 -07:00
wangyu-
46b0a00b3e Update README.md 2017-08-11 01:53:03 -07:00
wangyu-
d1934dda4c Update README.md 2017-08-11 01:52:29 -07:00
wangyu-
81e599e84c Update README.zh-cn.md 2017-08-11 01:50:25 -07:00
wangyu-
fadf5a25c2 Update README.zh-cn.md 2017-08-11 01:49:56 -07:00
wangyu-
9f25a61dad Update README.md 2017-08-11 01:47:20 -07:00
wangyu-
165dc193f0 Update README.md 2017-08-11 01:45:53 -07:00
wangyu-
e732ce2a8a Update README.md 2017-08-11 01:33:20 -07:00
wangyu-
d7cae0be18 Update README.md 2017-08-11 01:32:55 -07:00
wangyu
c1b8eb23a2 english build_guide 2017-08-11 16:30:22 +08:00
wangyu
1bbe19cdee Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-11 16:17:43 +08:00
wangyu
b16b37c879 fixed cmake 2017-08-11 16:17:26 +08:00
wangyu-
9479c95510 Update README.md 2017-08-10 23:49:55 -07:00
wangyu-
90b1897d4a Update README.md 2017-08-10 23:49:24 -07:00
wangyu-
3fa1a99046 Update README.zh-cn.md 2017-08-10 23:47:36 -07:00
wangyu-
eb59012b7b Update README.md 2017-08-10 23:31:42 -07:00
wangyu-
1a2cd767c0 Update README.zh-cn.md 2017-08-10 23:06:34 -07:00
wangyu-
8f04c82788 Update README.md 2017-08-10 22:53:01 -07:00
wangyu-
1b9f2a1e0e Update README.md 2017-08-10 22:51:50 -07:00
wangyu-
7592729abc Update README.md 2017-08-10 22:42:00 -07:00
wangyu
e890a6344c reverted extern c syntax,fixed a makefile problem 2017-08-11 12:25:04 +08:00
wangyu-
bc6358aa0a Merge pull request #3 from BroncoTc/master
merged pull request "add cmake support and fix compile errors“
2017-08-11 11:39:05 +08:00
broncotc
ed6416a30d add cmake support and fix compile errors 2017-08-11 10:45:40 +08:00
wangyu-
9378cee8d1 Update kcptun_step_by_step.md 2017-08-10 08:46:05 -07:00
wangyu-
0b3fb41f6f Update kcptun_step_by_step.md 2017-08-10 08:45:45 -07:00
wangyu-
41489af1d1 Update build_guide.zh-cn.md 2017-08-10 07:15:10 -07:00
wangyu
3a1bacc11e Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-10 22:08:18 +08:00
wangyu-
06d7638c5f Update README.zh-cn.md 2017-08-10 07:08:21 -07:00
wangyu
380971fe2b modified makefile 2017-08-10 22:08:09 +08:00
wangyu-
709258b260 Update build_guide.zh-cn.md 2017-08-10 07:04:45 -07:00
wangyu-
c3a8305e49 Update build_guide.zh-cn.md 2017-08-10 07:03:57 -07:00
wangyu-
5c08d65d91 Update build_guide.zh-cn.md 2017-08-10 07:03:38 -07:00
wangyu-
6f9ab92c1d Create build_guide.zh-cn.md 2017-08-10 06:20:51 -07:00
wangyu-
2f57fa6670 Update openvpn_guide.md 2017-08-10 05:39:06 -07:00
wangyu-
d104074328 Update README.zh-cn.md 2017-08-10 03:21:34 -07:00
wangyu-
7c280ab335 Update README.md 2017-08-10 03:20:35 -07:00
wangyu-
eb8567b693 Update README.zh-cn.md 2017-08-10 00:05:47 -07:00
wangyu-
fec382ebab Update README.zh-cn.md 2017-08-09 23:46:03 -07:00
wangyu-
4d319f54ff Update README.zh-cn.md 2017-08-09 23:44:41 -07:00
wangyu-
a58618c73c Update README.zh-cn.md 2017-08-09 23:39:53 -07:00
wangyu-
456da000f4 Update README.zh-cn.md 2017-08-09 23:37:30 -07:00
wangyu-
91e229616c Update README.md 2017-08-09 20:49:44 -07:00
wangyu
2251947278 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-09 21:30:10 +08:00
wangyu
c48c619002 added mtu warning 2017-08-09 21:29:54 +08:00
wangyu-
0cac945a26 Update kcptun_step_by_step.md 2017-08-09 06:04:18 -07:00
wangyu-
97738ab3ce Update finalspeed_step_by_step.md 2017-08-09 06:03:25 -07:00
wangyu-
a6bb0b50cf Update finalspeed_step_by_step.md 2017-08-09 06:02:30 -07:00
wangyu-
e7530fa7f9 Update README.zh-cn.md 2017-08-09 05:15:03 -07:00
wangyu-
cec1257474 Update README.zh-cn.md 2017-08-08 19:09:51 -07:00
wangyu
c97f09f534 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-09 09:18:41 +08:00
wangyu
92581be9a1 generates udp2raw_binaries.tar.gz in makefile 2017-08-09 09:18:27 +08:00
wangyu-
58ab1f6b15 Update README.zh-cn.md 2017-08-08 08:57:07 -07:00
wangyu-
1b0d4f6d08 Update README.zh-cn.md 2017-08-08 01:24:34 -07:00
wangyu
91a015b8a8 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-08 15:49:28 +08:00
wangyu
ce2e6a094d added send-direction failure direction,x86 binary 2017-08-08 15:49:11 +08:00
wangyu-
59af4a0135 Update README.md 2017-08-07 18:54:55 -07:00
wangyu-
b5c6176079 Add files via upload 2017-08-08 09:54:31 +08:00
wangyu-
83abc1def4 Update kcptun_step_by_step.md 2017-08-07 16:05:27 -07:00
wangyu
307399b00a added option lower-level 2017-08-07 23:42:09 +08:00
wangyu-
44852270ef Create openvpn_guide.md 2017-08-06 22:03:13 -07:00
wangyu-
ae153ceacc Update finalspeed_step_by_step.md 2017-08-06 19:43:18 -07:00
wangyu-
da6aafba12 Update README.md 2017-08-06 19:33:25 -07:00
wangyu-
e50d368440 Update finalspeed_step_by_step.md 2017-08-06 09:28:26 -07:00
wangyu-
801ecfd0ee Update README.zh-cn.md 2017-08-06 08:28:11 -07:00
wangyu-
45b7ab6285 Update README.zh-cn.md ,tcptun_step_by_step.md,finalspeed_step_by_step.md 2017-08-06 23:18:16 +08:00
wangyu-
8271cce383 Update README.zh-cn.md 2017-08-06 00:43:44 -07:00
wangyu
00dcec9896 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-06 14:50:50 +08:00
wangyu
6be7034bcb chinese readme 2017-08-06 14:50:27 +08:00
wangyu-
9593528dd4 Update README.md 2017-08-05 23:21:09 -07:00
wangyu-
9884544e34 Update README.md 2017-08-05 23:11:36 -07:00
wangyu-
858928a17f Update README.md 2017-08-05 23:10:26 -07:00
wangyu-
dc6c328d57 Update README.md 2017-08-06 13:12:23 +08:00
wangyu-
716c183886 Update README.md 2017-08-05 06:48:55 -07:00
141 changed files with 47769 additions and 5357 deletions

4
.clang-format Normal file
View File

@ -0,0 +1,4 @@
SortIncludes: false
BasedOnStyle: Google
ColumnLimit: 0
IndentWidth: 4

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
lib/aes_acc/asm/* linguist-vendored

35
CMakeLists.txt Normal file
View File

@ -0,0 +1,35 @@
#note: experimental
# currently only used for generating `compile_commands.json` for clangd.
# to build this project, it's suggested to use `makefile` instead
cmake_minimum_required(VERSION 3.7)
project(udp2raw)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES
main.cpp
lib/md5.cpp
lib/pbkdf2-sha1.cpp
lib/pbkdf2-sha256.cpp
encrypt.cpp
log.cpp
network.cpp
common.cpp
connection.cpp
misc.cpp
fd_manager.cpp
client.cpp
server.cpp
lib/aes_faster_c/aes.cpp
lib/aes_faster_c/wrapper.cpp
my_ev.cpp
)
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers -O2 -g -fsanitize=address,undefined")
add_executable(udp2raw ${SOURCE_FILES})
target_link_libraries(udp2raw rt)
target_link_libraries(udp2raw pthread)
include_directories(SYSTEM "libev")
include_directories(".")

1
ISSUE_TEMPLATE.md Normal file
View File

@ -0,0 +1 @@
English Only.

231
README.md
View File

@ -1,14 +1,227 @@
# udp2raw-tunnel
udp2raw tunnel (udp to tcp with fake tcp header)
# Udp2raw-tunnel
#usage
client:
-A INPUT -s 44.55.66.77/32 -p tcp -m tcp --sport 9999 -j DROP
A Tunnel which turns UDP Traffic into Encrypted FakeTCP/UDP/ICMP Traffic by using Raw Socket, helps you Bypass UDP FireWalls(or Unstable UDP Environment).
./raw -l 127.0.0.1:6666 -r44.55.66.77:9999 -c --source-ip 192.168.1.100
When used alone,udp2raw tunnels only UDP traffic. Nevertheless,if you used udp2raw + any UDP-based VPN together,you can tunnel any traffic(include TCP/UDP/ICMP),currently OpenVPN/L2TP/ShadowVPN and [tinyfecVPN](https://github.com/wangyu-/tinyfecVPN) are confirmed to be supported.
server:
-A INPUT -p tcp -m tcp --dport 9999 -j DROP
./raw -l44.55.66.77:9999 -r 127.0.0.1:5555 -s
![image0](images/image0.PNG)
or
![image_vpn](images/udp2rawopenvpn.PNG)
[udp2raw wiki](https://github.com/wangyu-/udp2raw-tunnel/wiki)
[简体中文](/doc/README.zh-cn.md)
# Support Platforms
Linux host (including desktop Linux,Android phone/tablet,OpenWRT router,or Raspberry PI) with root account or cap_net_raw capability.
For Windows and MacOS users, use the udp2raw in [this repo](https://github.com/wangyu-/udp2raw-multiplatform).
# Features
### Send/Receive UDP Packets with ICMP/FakeTCP/UDP headers
ICMP/FakeTCP headers help you bypass UDP blocking, UDP QOS or improper UDP NAT behavior on some ISPs. In ICMP header mode,udp2raw works like an ICMP tunnel.
UDP headers are also supported. In UDP header mode, it behaves just like a normal UDP tunnel, and you can just make use of the other features (such as encryption, anti-replay, or connection stabilization).
### Simulated TCP with Real-time/Out-of-Order Delivery
In FakeTCP header mode,udp2raw simulates 3-way handshake while establishing a connection,simulates seq and ack_seq while data transferring. It also simulates a few TCP options such as: `MSS`, `sackOk`, `TS`, `TS_ack`, `wscale`. Firewalls will regard FakeTCP as a TCP connection, but its essentially UDP: it supports real-time/out-of-order delivery(just as normal UDP does), no congestion control or re-transmission. So there wont be any TCP over TCP problem when using OpenVPN.
### Encryption, Anti-Replay
* Encrypt your traffic with AES-128-CBC.
* Protect data integrity by HMAC-SHA1 (or weaker MD5/CRC32).
* Defense replay attack with anti-replay window.
[Notes on encryption](https://github.com/wangyu-/udp2raw-tunnel/wiki/Notes-on-encryption)
### Failure Dectection & Stabilization (Connection Recovery)
Conection failures are detected by heartbeats. If timed-out, client will automatically change port number and reconnect. If reconnection is successful, the previous connection will be recovered, and all existing UDP conversations will stay vaild.
For example, if you use udp2raw + OpenVPN, OpenVPN won't lose connection after any reconnect, **even if network cable is re-plugged or WiFi access point is changed**.
### Other Features
* **Multiplexing** One client can handle multiple UDP connections, all of which share the same raw connection.
* **Multiple Clients** One server can have multiple clients.
* **NAT Support** All of the 3 modes work in NAT environments.
* **OpenVZ Support** Tested on BandwagonHost VPS.
* **Easy to Build** No dependencies.To cross-compile udp2raw,all you need to do is just to download a toolchain,modify makefile to point at the toolchain,run `make cross` then everything is done.(Note:Pre-compiled binaries for Desktop,RaspberryPi,Android,some Openwrt Routers are already included in [Releases](https://github.com/wangyu-/udp2raw-tunnel/releases))
### Keywords
`Bypass UDP QoS` `Bypass UDP Blocking` `Bypass OpenVPN TCP over TCP problem` `OpenVPN over ICMP` `UDP to ICMP tunnel` `UDP to TCP tunnel` `UDP over ICMP` `UDP over TCP`
# Getting Started
### Installing
Download binary release from https://github.com/wangyu-/udp2raw-tunnel/releases
### Running
Assume your UDP is blocked or being QOS-ed or just poorly supported. Assume your server ip is 44.55.66.77, you have a service listening on udp port 7777.
```bash
# Run at server side:
./udp2raw_amd64 -s -l0.0.0.0:4096 -r 127.0.0.1:7777 -k "passwd" --raw-mode faketcp -a
# Run at client side
./udp2raw_amd64 -c -l0.0.0.0:3333 -r44.55.66.77:4096 -k "passwd" --raw-mode faketcp -a
```
(The above commands need to be run as root. For better security, with some extra steps, you can run udp2raw as non-root. Check [this link](https://github.com/wangyu-/udp2raw-tunnel/wiki/run-udp2raw-as-non-root) for more info )
###### Server Output:
![](images/output_server.PNG)
###### Client Output:
![](images/output_client.PNG)
Now,an encrypted raw tunnel has been established between client and server through TCP port 4096. Connecting to UDP port 3333 at the client side is equivalent to connecting to port 7777 at the server side. No UDP traffic will be exposed.
### Note
To run on Android, check [Android_Guide](https://github.com/wangyu-/udp2raw/wiki/Android-Guide)
`-a` option automatically adds an iptables rule (or a few iptables rules) for you, udp2raw relies on this iptables rule to work stably. Be aware you dont forget `-a` (its a common mistake). If you dont want udp2raw to add iptables rule automatically, you can add it manually(take a look at `-g` option) and omit `-a`.
# Advanced Topic
### Usage
```
udp2raw-tunnel
git version:6e1df4b39f build date:Oct 24 2017 09:21:15
repository: https://github.com/wangyu-/udp2raw-tunnel
usage:
run as client : ./this_program -c -l local_listen_ip:local_port -r server_address:server_port [options]
run as server : ./this_program -s -l server_listen_ip:server_port -r remote_address:remote_port [options]
common options,these options must be same on both side:
--raw-mode <string> avaliable values:faketcp(default),udp,icmp
-k,--key <string> password to gen symetric key,default:"secret key"
--cipher-mode <string> avaliable values:aes128cbc(default),xor,none
--auth-mode <string> avaliable values:hmac_sha1,md5(default),crc32,simple,none
-a,--auto-rule auto add (and delete) iptables rule
-g,--gen-rule generate iptables rule then exit,so that you can copy and
add it manually.overrides -a
--disable-anti-replay disable anti-replay,not suggested
client options:
--source-ip <ip> force source-ip for raw socket
--source-port <port> force source-port for raw socket,tcp/udp only
this option disables port changing while re-connecting
other options:
--conf-file <string> read options from a configuration file instead of command line.
check example.conf in repo for format
--fifo <string> use a fifo(named pipe) for sending commands to the running program,
check readme.md in repository for supported commands.
--log-level <number> 0:never 1:fatal 2:error 3:warn
4:info (default) 5:debug 6:trace
--log-position enable file name,function name,line number in log
--disable-color disable log color
--disable-bpf disable the kernel space filter,most time its not necessary
unless you suspect there is a bug
--sock-buf <number> buf size for socket,>=10 and <=10240,unit:kbyte,default:1024
--force-sock-buf bypass system limitation while setting sock-buf
--seq-mode <number> seq increase mode for faketcp:
0:static header,do not increase seq and ack_seq
1:increase seq for every packet,simply ack last seq
2:increase seq randomly, about every 3 packets,simply ack last seq
3:simulate an almost real seq/ack procedure(default)
4:similiar to 3,but do not consider TCP Option Window_Scale,
maybe useful when firewall doesnt support TCP Option
--lower-level <string> send packets at OSI level 2, format:'if_name#dest_mac_adress'
ie:'eth0#00:23:45:67:89:b9'.or try '--lower-level auto' to obtain
the parameter automatically,specify it manually if 'auto' failed
--gen-add generate iptables rule and add it permanently,then exit.overrides -g
--keep-rule monitor iptables and auto re-add if necessary.implys -a
--clear clear any iptables rules added by this program.overrides everything
-h,--help print this help message
```
### Iptables rules,`-a` and `-g`
This program sends packets via raw socket. In FakeTCP mode, Linux kernel TCP packet processing has to be blocked by a iptables rule on both sides, otherwise the kernel will automatically send RST for an unrecongized TCP packet and you will sustain from stability / peformance problems. You can use `-a` option to let the program automatically add / delete iptables rule on start / exit. You can also use the `-g` option to generate iptables rule and add it manually.
### `--cipher-mode` and `--auth-mode`
It is suggested to use `aes128cbc` + `hmac_sha1` to obtain maximum security. If you want to run the program on a router, you can try `xor` + `simple`, which can fool packet inspection by firewalls the most of time, but it cannot protect you from serious attacks. Mode none is only for debugging purpose. It is not recommended to set the cipher-mode or auth-mode to none.
### `--seq-mode`
The FakeTCP mode does not behave 100% like a real tcp connection. ISPs may be able to distinguish the simulated tcp traffic from the real TCP traffic (though it's costly). seq-mode can help you change the seq increase behavior slightly. If you experience connection problems, try to change the value.
### `--lower-level`
`--lower-level` allows you to send packet at OSI level 2(link level),so that you can bypass any local iptables rules. If you have a complicated iptables rules which conflicts with udp2raw and you cant(or too lazy to) edit the iptables rules,`--lower-level` can be very useful. Try `--lower-level auto` to auto detect the parameters,you can specify it manually if `auto` fails.
Manual format `if_name#dest_mac_adress`,ie:`eth0#00:23:45:67:89:b9`.
### `--keep-rule`
Monitor iptables and auto re-add iptables rules(for blocking kernel tcp processing) if necessary.Especially useful when iptables rules may be cleared by other programs(for example,if you are using openwrt,everytime you changed and commited a setting,iptables rule may be cleared and re-constructed).
### `--conf-file`
You can also load options from a configuration file in order to keep secrets away from `ps` command.
For example, rewrite the options for the above `server` example (in Getting Started section) into configuration file:
`server.conf`
```
-s
# You can add comments like this
# Comments MUST occupy an entire line
# Or they will not work as expected
# Listen address
-l 0.0.0.0:4096
# Remote address
-r 127.0.0.1:7777
-a
-k passwd
--raw-mode faketcp
```
Pay attention to the `-k` parameter: In command line mode the quotes around the password will be removed by shell. In configuration files we do not remove quotes.
Then start the server with
```bash
./udp2raw_amd64 --conf-file server.conf
```
### `--fifo`
Use a fifo(named pipe) for sending commands to the running program. For example `--fifo fifo.file`.
At client side,you can use `echo reconnect >fifo.file` to force client to reconnect.Currently no command has been implemented for server.
# Peformance Test
#### Test method:
iperf3 TCP via OpenVPN + udp2raw
(iperf3 UDP mode is not used because of a bug mentioned in this issue: https://github.com/esnet/iperf/issues/296 . Instead, we package the TCP traffic into UDP by OpenVPN to test the performance. Read [Application](https://github.com/wangyu-/udp2raw-tunnel#application) for details.
#### iperf3 command:
```
iperf3 -c 10.222.2.1 -P40
iperf3 -c 10.222.2.1 -P40 -R
```
#### Environments
* **Client** Vultr $2.5/monthly plan (single core 2.4GHz cpu, 512MB RAM, Tokyo, Japan)
* **Server** BandwagonHost $3.99/annually plan (single core 2.0GHz cpu, 128MB RAM, Los Angeles, USA)
### Test1
raw_mode: faketcp cipher_mode: xor  auth_mode: simple
![image4](images/image4.PNG)
(reverse speed was simliar and not uploaded)
### Test2
raw_mode: faketcp cipher_mode: aes128cbc  auth_mode: md5
![image5](images/image5.PNG)
(reverse speed was simliar and not uploaded)
# wiki
Check wiki for more info:
https://github.com/wangyu-/udp2raw-tunnel/wiki

895
client.cpp Normal file
View File

@ -0,0 +1,895 @@
#include "common.h"
#include "network.h"
#include "connection.h"
#include "misc.h"
#include "log.h"
#include "lib/md5.h"
#include "encrypt.h"
#include "fd_manager.h"
#ifdef UDP2RAW_MP
u32_t detect_interval = 1500;
u64_t laste_detect_time = 0;
int use_udp_for_detection = 0;
int use_tcp_for_detection = 1;
extern pcap_t *pcap_handle;
extern int pcap_captured_full_len;
#endif
int client_on_timer(conn_info_t &conn_info) // for client. called when a timer is ready in epoll
{
packet_info_t &send_info = conn_info.raw_info.send_info;
packet_info_t &recv_info = conn_info.raw_info.recv_info;
raw_info_t &raw_info = conn_info.raw_info;
conn_info.blob->conv_manager.c.clear_inactive();
mylog(log_trace, "timer!\n");
mylog(log_trace, "roller my %d,oppsite %d,%lld\n", int(conn_info.my_roller), int(conn_info.oppsite_roller), conn_info.last_oppsite_roller_time);
mylog(log_trace, "<client_on_timer,send_info.ts_ack= %u>\n", send_info.ts_ack);
#ifdef UDP2RAW_MP
// mylog(log_debug,"pcap cnt :%d\n",pcap_cnt);
if (send_with_pcap && !pcap_header_captured) {
if (get_current_time() - laste_detect_time > detect_interval) {
laste_detect_time = get_current_time();
} else {
return 0;
}
/*
struct sockaddr_in remote_addr_in={0};
socklen_t slen = sizeof(sockaddr_in);
int port=get_true_random_number()%65534+1;
remote_addr_in.sin_family = AF_INET;
remote_addr_in.sin_port = htons(port);
remote_addr_in.sin_addr.s_addr = remote_ip_uint32;*/
int port = get_true_random_number() % 65534 + 1;
address_t tmp_addr = remote_addr;
tmp_addr.set_port(port);
if (use_udp_for_detection) {
int new_udp_fd = socket(tmp_addr.get_type(), SOCK_DGRAM, IPPROTO_UDP);
if (new_udp_fd < 0) {
mylog(log_warn, "create new_udp_fd error\n");
return -1;
}
setnonblocking(new_udp_fd);
u64_t tmp = get_true_random_number();
int ret = sendto(new_udp_fd, (char *)(&tmp), sizeof(tmp), 0, (struct sockaddr *)&tmp_addr.inner, tmp_addr.get_len());
if (ret == -1) {
mylog(log_warn, "sendto() failed\n");
}
sock_close(new_udp_fd);
}
if (use_tcp_for_detection) {
static int last_tcp_fd = -1;
int new_tcp_fd = socket(tmp_addr.get_type(), SOCK_STREAM, IPPROTO_TCP);
if (new_tcp_fd < 0) {
mylog(log_warn, "create new_tcp_fd error\n");
return -1;
}
setnonblocking(new_tcp_fd);
connect(new_tcp_fd, (struct sockaddr *)&tmp_addr.inner, tmp_addr.get_len());
if (last_tcp_fd != -1)
sock_close(last_tcp_fd);
last_tcp_fd = new_tcp_fd;
// close(new_tcp_fd);
}
mylog(log_info, "waiting for a use-able packet to be captured\n");
return 0;
}
#endif
if (raw_info.disabled) {
conn_info.state.client_current_state = client_idle;
conn_info.my_id = get_true_random_number_nz();
mylog(log_info, "state back to client_idle\n");
}
if (conn_info.state.client_current_state == client_idle) {
raw_info.rst_received = 0;
raw_info.disabled = 0;
fail_time_counter++;
if (max_fail_time > 0 && fail_time_counter > max_fail_time) {
mylog(log_fatal, "max_fail_time exceed\n");
myexit(-1);
}
conn_info.blob->anti_replay.re_init();
conn_info.my_id = get_true_random_number_nz(); /// todo no need to do this everytime
address_t tmp_addr;
// u32_t new_ip=0;
if (!force_source_ip) {
if (get_src_adress2(tmp_addr, remote_addr) != 0) {
mylog(log_warn, "get_src_adress() failed\n");
return -1;
}
// source_addr=new_addr;
// source_addr.set_port(0);
mylog(log_info, "source_addr is now %s\n", tmp_addr.get_ip());
/*
if(new_ip!=source_ip_uint32)
{
mylog(log_info,"source ip changed from %s to ",my_ntoa(source_ip_uint32));
log_bare(log_info,"%s\n",my_ntoa(new_ip));
source_ip_uint32=new_ip;
send_info.src_ip=new_ip;
}*/
} else {
tmp_addr = source_addr;
}
send_info.new_src_ip.from_address_t(tmp_addr);
if (force_source_port == 0) {
send_info.src_port = client_bind_to_a_new_port2(bind_fd, tmp_addr);
} else {
send_info.src_port = source_port;
}
if (raw_mode == mode_icmp) {
send_info.dst_port = send_info.src_port;
}
mylog(log_info, "using port %d\n", send_info.src_port);
init_filter(send_info.src_port);
if (raw_mode == mode_icmp || raw_mode == mode_udp) {
conn_info.state.client_current_state = client_handshake1;
mylog(log_info, "state changed from client_idle to client_pre_handshake\n");
}
if (raw_mode == mode_faketcp) {
if (use_tcp_dummy_socket) {
setnonblocking(bind_fd);
int ret = connect(bind_fd, (struct sockaddr *)&remote_addr.inner, remote_addr.get_len());
mylog(log_debug, "ret=%d,errno=%s, %d %s\n", ret, get_sock_error(), bind_fd, remote_addr.get_str());
// mylog(log_info,"ret=%d,errno=,%d %s\n",ret,bind_fd,remote_addr.get_str());
conn_info.state.client_current_state = client_tcp_handshake_dummy;
mylog(log_info, "state changed from client_idle to client_tcp_handshake_dummy\n");
} else {
conn_info.state.client_current_state = client_tcp_handshake;
mylog(log_info, "state changed from client_idle to client_tcp_handshake\n");
}
}
conn_info.last_state_time = get_current_time();
conn_info.last_hb_sent_time = 0;
// dont return;
}
if (conn_info.state.client_current_state == client_tcp_handshake) // send and resend syn
{
assert(raw_mode == mode_faketcp);
if (get_current_time() - conn_info.last_state_time > client_handshake_timeout) {
conn_info.state.client_current_state = client_idle;
mylog(log_info, "state back to client_idle from client_tcp_handshake\n");
return 0;
} else if (get_current_time() - conn_info.last_hb_sent_time > client_retry_interval) {
if (raw_mode == mode_faketcp) {
if (conn_info.last_hb_sent_time == 0) {
send_info.psh = 0;
send_info.syn = 1;
send_info.ack = 0;
send_info.ts_ack = 0;
send_info.seq = get_true_random_number();
send_info.ack_seq = get_true_random_number();
}
}
send_raw0(raw_info, 0, 0);
conn_info.last_hb_sent_time = get_current_time();
mylog(log_info, "(re)sent tcp syn\n");
return 0;
} else {
return 0;
}
return 0;
} else if (conn_info.state.client_current_state == client_tcp_handshake_dummy) {
assert(raw_mode == mode_faketcp);
if (get_current_time() - conn_info.last_state_time > client_handshake_timeout) {
conn_info.state.client_current_state = client_idle;
mylog(log_info, "state back to client_idle from client_tcp_handshake_dummy\n");
return 0;
}
} else if (conn_info.state.client_current_state == client_handshake1) // send and resend handshake1
{
if (get_current_time() - conn_info.last_state_time > client_handshake_timeout) {
conn_info.state.client_current_state = client_idle;
mylog(log_info, "state back to client_idle from client_handshake1\n");
return 0;
} else if (get_current_time() - conn_info.last_hb_sent_time > client_retry_interval) {
if (raw_mode == mode_faketcp) {
if (conn_info.last_hb_sent_time == 0) {
send_info.seq++;
send_info.ack_seq = recv_info.seq + 1;
send_info.ts_ack = recv_info.ts;
raw_info.reserved_send_seq = send_info.seq;
}
send_info.seq = raw_info.reserved_send_seq;
send_info.psh = 0;
send_info.syn = 0;
send_info.ack = 1;
if (!use_tcp_dummy_socket)
send_raw0(raw_info, 0, 0);
send_handshake(raw_info, conn_info.my_id, 0, const_id);
send_info.seq += raw_info.send_info.data_len;
} else {
send_handshake(raw_info, conn_info.my_id, 0, const_id);
if (raw_mode == mode_icmp)
send_info.my_icmp_seq++;
}
conn_info.last_hb_sent_time = get_current_time();
mylog(log_info, "(re)sent handshake1\n");
return 0;
} else {
return 0;
}
return 0;
} else if (conn_info.state.client_current_state == client_handshake2) {
if (get_current_time() - conn_info.last_state_time > client_handshake_timeout) {
conn_info.state.client_current_state = client_idle;
mylog(log_info, "state back to client_idle from client_handshake2\n");
return 0;
} else if (get_current_time() - conn_info.last_hb_sent_time > client_retry_interval) {
if (raw_mode == mode_faketcp) {
if (conn_info.last_hb_sent_time == 0) {
send_info.ack_seq = recv_info.seq + raw_info.recv_info.data_len;
send_info.ts_ack = recv_info.ts;
raw_info.reserved_send_seq = send_info.seq;
}
send_info.seq = raw_info.reserved_send_seq;
send_handshake(raw_info, conn_info.my_id, conn_info.oppsite_id, const_id);
send_info.seq += raw_info.send_info.data_len;
} else {
send_handshake(raw_info, conn_info.my_id, conn_info.oppsite_id, const_id);
if (raw_mode == mode_icmp)
send_info.my_icmp_seq++;
}
conn_info.last_hb_sent_time = get_current_time();
mylog(log_info, "(re)sent handshake2\n");
return 0;
} else {
return 0;
}
return 0;
} else if (conn_info.state.client_current_state == client_ready) {
fail_time_counter = 0;
mylog(log_trace, "time %llu,%llu\n", get_current_time(), conn_info.last_state_time);
if (get_current_time() - conn_info.last_hb_recv_time > client_conn_timeout) {
conn_info.state.client_current_state = client_idle;
conn_info.my_id = get_true_random_number_nz();
mylog(log_info, "state back to client_idle from client_ready bc of server-->client direction timeout\n");
return 0;
}
if (get_current_time() - conn_info.last_oppsite_roller_time > client_conn_uplink_timeout) {
conn_info.state.client_current_state = client_idle;
conn_info.my_id = get_true_random_number_nz();
mylog(log_info, "state back to client_idle from client_ready bc of client-->server direction timeout\n");
}
if (get_current_time() - conn_info.last_hb_sent_time < heartbeat_interval) {
return 0;
}
mylog(log_debug, "heartbeat sent <%x,%x>\n", conn_info.oppsite_id, conn_info.my_id);
if (hb_mode == 0)
send_safer(conn_info, 'h', hb_buf, 0); /////////////send
else
send_safer(conn_info, 'h', hb_buf, hb_len);
conn_info.last_hb_sent_time = get_current_time();
return 0;
} else {
mylog(log_fatal, "unknown state,this shouldnt happen.\n");
myexit(-1);
}
return 0;
}
int client_on_raw_recv_hs2_or_ready(conn_info_t &conn_info, char type, char *data, int data_len) {
packet_info_t &send_info = conn_info.raw_info.send_info;
packet_info_t &recv_info = conn_info.raw_info.recv_info;
if (!recv_info.new_src_ip.equal(send_info.new_dst_ip) || recv_info.src_port != send_info.dst_port) {
mylog(log_warn, "unexpected adress %s %s %d %d,this shouldnt happen.\n", recv_info.new_src_ip.get_str1(), send_info.new_dst_ip.get_str2(), recv_info.src_port, send_info.dst_port);
return -1;
}
if (conn_info.state.client_current_state == client_handshake2) {
mylog(log_info, "changed state from to client_handshake2 to client_ready\n");
conn_info.state.client_current_state = client_ready;
conn_info.last_hb_sent_time = 0;
conn_info.last_hb_recv_time = get_current_time();
conn_info.last_oppsite_roller_time = conn_info.last_hb_recv_time;
client_on_timer(conn_info);
}
if (data_len >= 0 && type == 'h') {
mylog(log_debug, "[hb]heart beat received,oppsite_roller=%d\n", int(conn_info.oppsite_roller));
conn_info.last_hb_recv_time = get_current_time();
return 0;
} else if (data_len >= int(sizeof(u32_t)) && type == 'd') {
mylog(log_trace, "received a data from fake tcp,len:%d\n", data_len);
if (hb_mode == 0)
conn_info.last_hb_recv_time = get_current_time();
u32_t tmp_conv_id;
memcpy(&tmp_conv_id, &data[0], sizeof(tmp_conv_id));
tmp_conv_id = ntohl(tmp_conv_id);
if (!conn_info.blob->conv_manager.c.is_conv_used(tmp_conv_id)) {
mylog(log_info, "unknow conv %d,ignore\n", tmp_conv_id);
return 0;
}
conn_info.blob->conv_manager.c.update_active_time(tmp_conv_id);
// u64_t u64=conn_info.blob->conv_manager.c.find_data_by_conv(tmp_conv_id);
address_t tmp_addr = conn_info.blob->conv_manager.c.find_data_by_conv(tmp_conv_id);
// sockaddr_in tmp_sockaddr={0};
// tmp_sockaddr.sin_family = AF_INET;
// tmp_sockaddr.sin_addr.s_addr=(u64>>32u);
// tmp_sockaddr.sin_port= htons(uint16_t((u64<<32u)>>32u));
int ret = sendto(udp_fd, data + sizeof(u32_t), data_len - (sizeof(u32_t)), 0, (struct sockaddr *)&tmp_addr.inner, tmp_addr.get_len());
if (ret < 0) {
mylog(log_warn, "sento returned %d,%s,%02x,%s\n", ret, get_sock_error(), int(tmp_addr.get_type()), tmp_addr.get_str());
// perror("ret<0");
}
} else {
mylog(log_warn, "unknown packet,this shouldnt happen.\n");
return -1;
}
return 0;
}
int client_on_raw_recv(conn_info_t &conn_info) // called when raw fd received a packet.
{
char *data;
int data_len;
packet_info_t &send_info = conn_info.raw_info.send_info;
packet_info_t &recv_info = conn_info.raw_info.recv_info;
raw_info_t &raw_info = conn_info.raw_info;
mylog(log_trace, "<client_on_raw_recv,send_info.ts_ack= %u>\n", send_info.ts_ack);
#ifdef UDP2RAW_LINUX
if (pre_recv_raw_packet() < 0) return -1;
#endif
if (conn_info.state.client_current_state == client_idle) {
discard_raw_packet();
// recv(raw_recv_fd, 0,0, 0 );
} else if (conn_info.state.client_current_state == client_tcp_handshake || conn_info.state.client_current_state == client_tcp_handshake_dummy) // received syn ack
{
assert(raw_mode == mode_faketcp);
if (recv_raw0(raw_info, data, data_len) < 0) {
return -1;
}
if (data_len >= max_data_len + 1) {
mylog(log_debug, "data_len=%d >= max_data_len+1,ignored", data_len);
return -1;
}
if (!recv_info.new_src_ip.equal(send_info.new_dst_ip) || recv_info.src_port != send_info.dst_port) {
mylog(log_debug, "unexpected adress %s %s %d %d\n", recv_info.new_src_ip.get_str1(), send_info.new_dst_ip.get_str2(), recv_info.src_port, send_info.dst_port);
return -1;
}
if (data_len == 0 && raw_info.recv_info.syn == 1 && raw_info.recv_info.ack == 1) {
if (conn_info.state.client_current_state == client_tcp_handshake) {
if (recv_info.ack_seq != send_info.seq + 1) {
mylog(log_debug, "seq ack_seq mis match\n");
return -1;
}
mylog(log_info, "state changed from client_tcp_handshake to client_handshake1\n");
} else {
send_info.seq = recv_info.ack_seq - 1;
mylog(log_info, "state changed from client_tcp_dummy to client_handshake1\n");
// send_info.ack_seq=recv_info.seq+1;
}
conn_info.state.client_current_state = client_handshake1;
conn_info.last_state_time = get_current_time();
conn_info.last_hb_sent_time = 0;
client_on_timer(conn_info);
return 0;
} else {
mylog(log_debug, "unexpected packet type,expected:syn ack\n");
return -1;
}
} else if (conn_info.state.client_current_state == client_handshake1) // recevied respond of handshake1
{
if (recv_bare(raw_info, data, data_len) != 0) {
mylog(log_debug, "recv_bare failed!\n");
return -1;
}
if (!recv_info.new_src_ip.equal(send_info.new_dst_ip) || recv_info.src_port != send_info.dst_port) {
mylog(log_debug, "unexpected adress %s %s %d %d\n", recv_info.new_src_ip.get_str1(), send_info.new_dst_ip.get_str2(), recv_info.src_port, send_info.dst_port);
return -1;
}
if (data_len < int(3 * sizeof(my_id_t))) {
mylog(log_debug, "too short to be a handshake\n");
return -1;
}
my_id_t tmp_oppsite_id;
memcpy(&tmp_oppsite_id, &data[0], sizeof(tmp_oppsite_id));
tmp_oppsite_id = ntohl(tmp_oppsite_id);
my_id_t tmp_my_id;
memcpy(&tmp_my_id, &data[sizeof(my_id_t)], sizeof(tmp_my_id));
tmp_my_id = ntohl(tmp_my_id);
my_id_t tmp_oppsite_const_id;
memcpy(&tmp_oppsite_const_id, &data[sizeof(my_id_t) * 2], sizeof(tmp_oppsite_const_id));
tmp_oppsite_const_id = ntohl(tmp_oppsite_const_id);
if (tmp_my_id != conn_info.my_id) {
mylog(log_debug, "tmp_my_id doesnt match\n");
return -1;
}
if (raw_mode == mode_faketcp) {
if (recv_info.ack_seq != send_info.seq) {
mylog(log_debug, "seq ack_seq mis match\n");
return -1;
}
if (recv_info.seq != send_info.ack_seq) {
mylog(log_debug, "seq ack_seq mis match\n");
return -1;
}
}
conn_info.oppsite_id = tmp_oppsite_id;
mylog(log_info, "changed state from to client_handshake1 to client_handshake2,my_id is %x,oppsite id is %x\n", conn_info.my_id, conn_info.oppsite_id);
conn_info.state.client_current_state = client_handshake2;
conn_info.last_state_time = get_current_time();
conn_info.last_hb_sent_time = 0;
client_on_timer(conn_info);
return 0;
} else if (conn_info.state.client_current_state == client_handshake2 || conn_info.state.client_current_state == client_ready) // received heartbeat or data
{
vector<char> type_vec;
vector<string> data_vec;
recv_safer_multi(conn_info, type_vec, data_vec);
if (data_vec.empty()) {
mylog(log_debug, "recv_safer failed!\n");
return -1;
}
for (int i = 0; i < (int)type_vec.size(); i++) {
char type = type_vec[i];
char *data = (char *)data_vec[i].c_str(); // be careful, do not append data to it
int data_len = data_vec[i].length();
client_on_raw_recv_hs2_or_ready(conn_info, type, data, data_len);
}
return 0;
} else {
mylog(log_fatal, "unknown state,this shouldnt happen.\n");
myexit(-1);
}
return 0;
}
int client_on_udp_recv(conn_info_t &conn_info) {
int recv_len;
char buf[buf_len];
address_t::storage_t udp_new_addr_in = {{0}};
socklen_t udp_new_addr_len = sizeof(address_t::storage_t);
if ((recv_len = recvfrom(udp_fd, buf, max_data_len + 1, 0,
(struct sockaddr *)&udp_new_addr_in, &udp_new_addr_len)) == -1) {
mylog(log_debug, "recv_from error,%s\n", get_sock_error());
return -1;
// myexit(1);
};
if (recv_len == max_data_len + 1) {
mylog(log_warn, "huge packet, data_len > %d,dropped\n", max_data_len);
return -1;
}
if (recv_len >= mtu_warn) {
mylog(log_warn, "huge packet,data len=%d (>=%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ", recv_len, mtu_warn);
}
address_t tmp_addr;
tmp_addr.from_sockaddr((sockaddr *)&udp_new_addr_in, udp_new_addr_len);
u32_t conv;
if (!conn_info.blob->conv_manager.c.is_data_used(tmp_addr)) {
if (conn_info.blob->conv_manager.c.get_size() >= max_conv_num) {
mylog(log_warn, "ignored new udp connect bc max_conv_num exceed\n");
return -1;
}
conv = conn_info.blob->conv_manager.c.get_new_conv();
conn_info.blob->conv_manager.c.insert_conv(conv, tmp_addr);
mylog(log_info, "new packet from %s,conv_id=%x\n", tmp_addr.get_str(), conv);
} else {
conv = conn_info.blob->conv_manager.c.find_conv_by_data(tmp_addr);
}
conn_info.blob->conv_manager.c.update_active_time(conv);
if (conn_info.state.client_current_state == client_ready) {
send_data_safer(conn_info, buf, recv_len, conv);
}
return 0;
}
void udp_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
conn_info_t &conn_info = *((conn_info_t *)watcher->data);
client_on_udp_recv(conn_info);
}
void raw_recv_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
if (is_udp2raw_mp) assert(0 == 1);
conn_info_t &conn_info = *((conn_info_t *)watcher->data);
client_on_raw_recv(conn_info);
}
#ifdef UDP2RAW_MP
void async_cb(struct ev_loop *loop, struct ev_async *watcher, int revents) {
conn_info_t &conn_info = *((conn_info_t *)watcher->data);
if (send_with_pcap && !pcap_header_captured) {
int empty = 0;
char *p;
int len;
pthread_mutex_lock(&queue_mutex);
empty = my_queue.empty();
if (!empty) {
my_queue.peek_front(p, len);
my_queue.pop_front();
}
pthread_mutex_unlock(&queue_mutex);
if (empty) return;
pcap_header_captured = 1;
assert(pcap_link_header_len != -1);
memcpy(pcap_header_buf, p, max_data_len);
log_bare(log_info, "link level header captured:\n");
unsigned char *tmp = (unsigned char *)pcap_header_buf;
pcap_captured_full_len = len;
for (int i = 0; i < pcap_link_header_len; i++)
log_bare(log_info, "<%x>", (u32_t)tmp[i]);
log_bare(log_info, "\n");
return;
}
// mylog(log_info,"async_cb called\n");
while (1) {
int empty = 0;
char *p;
int len;
pthread_mutex_lock(&queue_mutex);
empty = my_queue.empty();
if (!empty) {
my_queue.peek_front(p, len);
my_queue.pop_front();
}
pthread_mutex_unlock(&queue_mutex);
if (empty) break;
if (g_fix_gro == 0 && len > max_data_len) {
mylog(log_warn, "huge packet %d > %d, dropped. maybe you need to turn down mtu at upper level, or maybe you need the --fix-gro option\n", len, max_data_len);
break;
}
int new_len = len - pcap_link_header_len;
memcpy(g_packet_buf, p + pcap_link_header_len, new_len);
g_packet_buf_len = new_len;
assert(g_packet_buf_cnt == 0);
g_packet_buf_cnt++;
client_on_raw_recv(conn_info);
}
}
#endif
void clear_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) {
conn_info_t &conn_info = *((conn_info_t *)watcher->data);
client_on_timer(conn_info);
}
void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
conn_info_t &conn_info = *((conn_info_t *)watcher->data);
char buf[buf_len];
int fifo_fd = watcher->fd;
int len = read(fifo_fd, buf, sizeof(buf));
if (len < 0) {
mylog(log_warn, "fifo read failed len=%d,errno=%s\n", len, get_sock_error());
return;
}
buf[len] = 0;
while (len >= 1 && buf[len - 1] == '\n')
buf[len - 1] = 0;
mylog(log_info, "got data from fifo,len=%d,s=[%s]\n", len, buf);
if (strcmp(buf, "reconnect") == 0) {
mylog(log_info, "received command: reconnect\n");
conn_info.state.client_current_state = client_idle;
conn_info.my_id = get_true_random_number_nz();
} else {
mylog(log_info, "unknown command\n");
}
}
int client_event_loop() {
char buf[buf_len];
conn_info_t conn_info;
conn_info.my_id = get_true_random_number_nz();
conn_info.prepare();
packet_info_t &send_info = conn_info.raw_info.send_info;
packet_info_t &recv_info = conn_info.raw_info.recv_info;
#ifdef UDP2RAW_LINUX
if (lower_level) {
if (lower_level_manual) {
int index;
init_ifindex(if_name, raw_send_fd, index);
// init_ifindex(if_name);
memset(&send_info.addr_ll, 0, sizeof(send_info.addr_ll));
send_info.addr_ll.sll_family = AF_PACKET;
send_info.addr_ll.sll_ifindex = index;
send_info.addr_ll.sll_halen = ETHER_ADDR_LEN;
send_info.addr_ll.sll_protocol = htons(ETH_P_IP);
memcpy(&send_info.addr_ll.sll_addr, dest_hw_addr, ETHER_ADDR_LEN);
mylog(log_info, "we are running at lower-level (manual) mode\n");
} else {
u32_t dest_ip;
string if_name_string;
string hw_string;
assert(remote_addr.get_type() == AF_INET);
if (retry_on_error == 0) {
if (find_lower_level_info(remote_addr.inner.ipv4.sin_addr.s_addr, dest_ip, if_name_string, hw_string) != 0) {
mylog(log_fatal, "auto detect lower-level info failed for %s,specific it manually\n", remote_addr.get_ip());
myexit(-1);
}
} else {
int ok = 0;
while (!ok) {
if (find_lower_level_info(remote_addr.inner.ipv4.sin_addr.s_addr, dest_ip, if_name_string, hw_string) != 0) {
mylog(log_warn, "auto detect lower-level info failed for %s,retry in %d seconds\n", remote_addr.get_ip(), retry_on_error_interval);
sleep(retry_on_error_interval);
} else {
ok = 1;
}
}
}
mylog(log_info, "we are running at lower-level (auto) mode,%s %s %s\n", my_ntoa(dest_ip), if_name_string.c_str(), hw_string.c_str());
u32_t hw[6];
memset(hw, 0, sizeof(hw));
sscanf(hw_string.c_str(), "%x:%x:%x:%x:%x:%x", &hw[0], &hw[1], &hw[2],
&hw[3], &hw[4], &hw[5]);
mylog(log_warn,
"make sure this is correct: if_name=<%s> dest_mac_adress=<%02x:%02x:%02x:%02x:%02x:%02x> \n",
if_name_string.c_str(), hw[0], hw[1], hw[2], hw[3], hw[4], hw[5]);
for (int i = 0; i < 6; i++) {
dest_hw_addr[i] = uint8_t(hw[i]);
}
// mylog(log_fatal,"--lower-level auto for client hasnt been implemented\n");
int index;
init_ifindex(if_name_string.c_str(), raw_send_fd, index);
memset(&send_info.addr_ll, 0, sizeof(send_info.addr_ll));
send_info.addr_ll.sll_family = AF_PACKET;
send_info.addr_ll.sll_ifindex = index;
send_info.addr_ll.sll_halen = ETHER_ADDR_LEN;
send_info.addr_ll.sll_protocol = htons(ETH_P_IP);
memcpy(&send_info.addr_ll.sll_addr, dest_hw_addr, ETHER_ADDR_LEN);
// mylog(log_info,"we are running at lower-level (manual) mode\n");
}
}
#endif
#ifdef UDP2RAW_MP
address_t tmp_addr;
if (get_src_adress2(tmp_addr, remote_addr) != 0) {
mylog(log_error, "get_src_adress() failed\n");
myexit(-1);
}
if (strcmp(dev, "") == 0) {
mylog(log_info, "--dev have not been set, trying to detect automatically, available devices:\n");
mylog(log_info, "available device(device name: ip address ; description):\n");
char errbuf[PCAP_ERRBUF_SIZE];
int found = 0;
pcap_if_t *interfaces, *d;
if (pcap_findalldevs(&interfaces, errbuf) == -1) {
mylog(log_fatal, "error in pcap_findalldevs(),%s\n", errbuf);
myexit(-1);
}
for (pcap_if_t *d = interfaces; d != NULL; d = d->next) {
log_bare(log_warn, "%s:", d->name);
int cnt = 0;
for (pcap_addr_t *a = d->addresses; a != NULL; a = a->next) {
if (a->addr == NULL) {
log_bare(log_debug, " [a->addr==NULL]");
continue;
}
if (a->addr->sa_family == AF_INET || a->addr->sa_family == AF_INET6) {
cnt++;
if (a->addr->sa_family == AF_INET) {
char s[max_addr_len];
inet_ntop(AF_INET, &((struct sockaddr_in *)a->addr)->sin_addr, s, max_addr_len);
log_bare(log_warn, " [%s]", s);
if (a->addr->sa_family == raw_ip_version) {
if (((struct sockaddr_in *)a->addr)->sin_addr.s_addr == tmp_addr.inner.ipv4.sin_addr.s_addr) {
found++;
strcpy(dev, d->name);
}
}
} else {
assert(a->addr->sa_family == AF_INET6);
char s[max_addr_len];
inet_ntop(AF_INET6, &((struct sockaddr_in6 *)a->addr)->sin6_addr, s, max_addr_len);
log_bare(log_warn, " [%s]", s);
if (a->addr->sa_family == raw_ip_version) {
if (memcmp(&((struct sockaddr_in6 *)a->addr)->sin6_addr, &tmp_addr.inner.ipv6.sin6_addr, sizeof(struct in6_addr)) == 0) {
found++;
strcpy(dev, d->name);
}
}
}
} else {
log_bare(log_debug, " [unknow:%d]", int(a->addr->sa_family));
}
}
if (cnt == 0) log_bare(log_warn, " [no ip found]");
if (d->description == 0) {
log_bare(log_warn, "; (no description available)");
} else {
log_bare(log_warn, "; %s", d->description);
}
log_bare(log_warn, "\n");
}
if (found == 0) {
mylog(log_fatal, "no matched device found for ip: [%s]\n", tmp_addr.get_ip());
myexit(-1);
} else if (found == 1) {
mylog(log_info, "using device:[%s], ip: [%s]\n", dev, tmp_addr.get_ip());
} else {
mylog(log_fatal, "more than one devices found for ip: [%s] , you need to use --dev manually\n", tmp_addr.get_ip());
myexit(-1);
}
} else {
mylog(log_info, "--dev has been manually set, using device:[%s]\n", dev);
}
#endif
send_info.src_port = 0;
memset(&send_info.new_src_ip, 0, sizeof(send_info.new_src_ip));
int i, j, k;
int ret;
send_info.new_dst_ip.from_address_t(remote_addr);
send_info.dst_port = remote_addr.get_port();
udp_fd = socket(local_addr.get_type(), SOCK_DGRAM, IPPROTO_UDP);
set_buf_size(udp_fd, socket_buf_size);
if (::bind(udp_fd, (struct sockaddr *)&local_addr.inner, local_addr.get_len()) == -1) {
mylog(log_fatal, "socket bind error\n");
// perror("socket bind error");
myexit(1);
}
setnonblocking(udp_fd);
// epollfd = epoll_create1(0);
// const int max_events = 4096;
// struct epoll_event ev, events[max_events];
// if (epollfd < 0) {
// mylog(log_fatal,"epoll return %d\n", epollfd);
// myexit(-1);
// }
struct ev_loop *loop = ev_default_loop(0);
assert(loop != NULL);
// ev.events = EPOLLIN;
// ev.data.u64 = udp_fd;
// ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, udp_fd, &ev);
// if (ret!=0) {
// mylog(log_fatal,"add udp_listen_fd error\n");
// myexit(-1);
// }
struct ev_io udp_accept_watcher;
udp_accept_watcher.data = &conn_info;
ev_io_init(&udp_accept_watcher, udp_accept_cb, udp_fd, EV_READ);
ev_io_start(loop, &udp_accept_watcher);
// ev.events = EPOLLIN;
// ev.data.u64 = raw_recv_fd;
// ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, raw_recv_fd, &ev);
// if (ret!= 0) {
// mylog(log_fatal,"add raw_fd error\n");
// myexit(-1);
// }
#ifdef UDP2RAW_LINUX
struct ev_io raw_recv_watcher;
raw_recv_watcher.data = &conn_info;
ev_io_init(&raw_recv_watcher, raw_recv_cb, raw_recv_fd, EV_READ);
ev_io_start(loop, &raw_recv_watcher);
#endif
#ifdef UDP2RAW_MP
g_default_loop = loop;
async_watcher.data = &conn_info;
ev_async_init(&async_watcher, async_cb);
ev_async_start(loop, &async_watcher);
init_raw_socket(); // must be put after dev detection
#endif
// set_timer(epollfd,timer_fd);
struct ev_timer clear_timer;
clear_timer.data = &conn_info;
ev_timer_init(&clear_timer, clear_timer_cb, 0, timer_interval / 1000.0);
ev_timer_start(loop, &clear_timer);
mylog(log_debug, "send_raw : from %s %d to %s %d\n", send_info.new_src_ip.get_str1(), send_info.src_port, send_info.new_dst_ip.get_str2(), send_info.dst_port);
int fifo_fd = -1;
struct ev_io fifo_watcher;
fifo_watcher.data = &conn_info;
if (fifo_file[0] != 0) {
fifo_fd = create_fifo(fifo_file);
ev_io_init(&fifo_watcher, fifo_cb, fifo_fd, EV_READ);
ev_io_start(loop, &fifo_watcher);
mylog(log_info, "fifo_file=%s\n", fifo_file);
}
ev_run(loop, 0);
return 0;
}

1156
common.cpp

File diff suppressed because it is too large Load Diff

551
common.h
View File

@ -5,103 +5,149 @@
* Author: wangyu
*/
#ifndef COMMON_H_
#define COMMON_H_
#ifndef UDP2RAW_COMMON_H_
#define UDP2RAW_COMMON_H_
#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<getopt.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include<unistd.h>
#include<errno.h>
#include <sys/epoll.h>
#include <sys/wait.h>
#include <sys/socket.h> //for socket ofcourse
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <stdlib.h> //for exit(0);
#include <errno.h> //For errno - the error number
#include <netinet/tcp.h> //Provides declarations for tcp header
#include <netinet/udp.h>
#include <netinet/ip.h> //Provides declarations for ip header
#include <netinet/if_ether.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <byteswap.h>
#include <arpa/inet.h>
#include <linux/if_ether.h>
#include <linux/filter.h>
#include <sys/time.h>
#include <time.h>
#include <sys/timerfd.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <stdarg.h>
#include <assert.h>
#include <pthread.h>
#ifndef USE_LIBNET
#define NO_LIBNET
#endif
#if defined(UDP2RAW_MP)
const int is_udp2raw_mp = 1;
#if !defined(__CYGWIN__) && !defined(__MINGW32__)
#include <pcap.h>
#else
#include <pcap_wrapper.h>
#define NO_LIBNET
#endif
#ifndef NO_LIBNET
#include <libnet.h>
#endif
#include<unordered_map>
#else
#define UDP2RAW_LINUX
const int is_udp2raw_mp = 0;
//#include <linux/if_ether.h>
#include <linux/filter.h>
#include <linux/if_packet.h>
#include <sys/epoll.h>
//#include <sys/wait.h> //signal
#include <netinet/if_ether.h>
#include <net/if.h>
#include <sys/timerfd.h>
#endif
#if !defined(NO_LIBEV_EMBED)
#include <my_ev.h>
#else
#include "ev.h"
#endif
#if defined(__MINGW32__)
#include <winsock2.h>
#include <ws2ipdef.h>
typedef unsigned char u_int8_t;
typedef unsigned short u_int16_t;
typedef unsigned int u_int32_t;
typedef int socklen_t;
#else
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#endif
#include <unordered_map>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <list>
using namespace std;
#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || \
defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ || \
defined(__BIG_ENDIAN__) || \
defined(__ARMEB__) || \
defined(__THUMBEB__) || \
defined(__AARCH64EB__) || \
defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__)
#define UDP2RAW_BIG_ENDIAN 1
#endif
typedef unsigned long long u64_t; //this works on most platform,avoid using the PRId64
#if defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || \
defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || \
defined(__LITTLE_ENDIAN__) || \
defined(__ARMEL__) || \
defined(__THUMBEL__) || \
defined(__AARCH64EL__) || \
defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__)
#define UDP2RAW_LITTLE_ENDIAN 1
#endif
#if defined(UDP2RAW_BIG_ENDIAN) && defined(UDP2RAW_LITTLE_ENDIAN)
#error "endian detection conflicts"
#endif
#if !defined(UDP2RAW_BIG_ENDIAN) && !defined(UDP2RAW_LITTLE_ENDIAN)
#error "endian detection failed"
#endif
#if defined(__MINGW32__)
int inet_pton(int af, const char *src, void *dst);
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
#define setsockopt(a, b, c, d, e) setsockopt(a, b, c, (const char *)(d), e)
#endif
char *get_sock_error();
int get_sock_errno();
#if defined(__MINGW32__)
typedef SOCKET my_fd_t;
inline int sock_close(my_fd_t fd) {
return closesocket(fd);
}
#else
typedef int my_fd_t;
inline int sock_close(my_fd_t fd) {
return close(fd);
}
#endif
typedef unsigned long long u64_t; // this works on most platform,avoid using the PRId64
typedef long long i64_t;
typedef unsigned int u32_t;
typedef int i32_t;
typedef unsigned short u16_t;
typedef short i16_t;
const int max_data_len=1600;
const int buf_len=max_data_len+200;
const u32_t max_handshake_conn_num=10000;
const u32_t max_ready_conn_num=1000;
const u32_t anti_replay_window_size=1000;
const int max_conv_num=10000;
const u32_t client_handshake_timeout=5000;
const u32_t client_retry_interval=1000;
const u32_t server_handshake_timeout=10000;// this should be much longer than clients. client retry initially ,server retry passtively
const int conv_clear_ratio=10; //conv grabage collecter check 1/10 of all conv one time
const int conn_clear_ratio=10;
const int conv_clear_min=5;
const int conn_clear_min=1;
const u32_t conv_clear_interval=1000;
const u32_t conn_clear_interval=1000;
const i32_t max_fail_time=0;//disable
const u32_t heartbeat_interval=1000;
const u32_t timer_interval=400;//this should be smaller than heartbeat_interval and retry interval;
//const uint32_t conv_timeout=120000; //120 second
const u32_t conv_timeout=30000; //for test
const u32_t client_conn_timeout=10000;
//const uint32_t server_conn_timeout=conv_timeout+60000;//this should be 60s+ longer than conv_timeout,so that conv_manager can destruct convs gradually,to avoid latency glicth
const u32_t server_conn_timeout=conv_timeout+10000;//for test
extern int about_to_exit;
enum raw_mode_t{mode_faketcp=0,mode_udp,mode_icmp,mode_end};
extern raw_mode_t raw_mode;
enum program_mode_t {unset_mode=0,client_mode,server_mode};
extern program_mode_t program_mode;
extern unordered_map<int, const char*> raw_mode_tostring ;
extern int socket_buf_size;
typedef u32_t id_t;
typedef u32_t my_id_t;
typedef u64_t iv_t;
@ -109,37 +155,368 @@ typedef u64_t padding_t;
typedef u64_t anti_replay_seq_t;
typedef u64_t my_time_t;
const int max_addr_len = 100;
extern int force_socket_buf;
extern int g_fix_gro;
/*
struct ip_port_t
{
u32_t ip;
int port;
void from_u64(u64_t u64);
u64_t to_u64();
char * to_s();
};*/
typedef u64_t fd64_t;
u32_t djb2(unsigned char *str, int len);
u32_t sdbm(unsigned char *str, int len);
struct address_t // TODO scope id
{
struct hash_function {
u32_t operator()(const address_t &key) const {
return sdbm((unsigned char *)&key.inner, sizeof(key.inner));
}
};
union storage_t // sockaddr_storage is too huge, we dont use it.
{
sockaddr_in ipv4;
sockaddr_in6 ipv6;
};
storage_t inner;
address_t() {
clear();
}
void clear() {
memset(&inner, 0, sizeof(inner));
}
int from_ip_port(u32_t ip, int port) {
clear();
inner.ipv4.sin_family = AF_INET;
inner.ipv4.sin_port = htons(port);
inner.ipv4.sin_addr.s_addr = ip;
return 0;
}
int from_ip_port_new(int type, void *ip, int port) {
clear();
if (type == AF_INET) {
inner.ipv4.sin_family = AF_INET;
inner.ipv4.sin_port = htons(port);
inner.ipv4.sin_addr.s_addr = *((u32_t *)ip);
} else if (type == AF_INET6) {
inner.ipv6.sin6_family = AF_INET6;
inner.ipv6.sin6_port = htons(port);
inner.ipv6.sin6_addr = *((in6_addr *)ip);
}
return 0;
}
int from_str(char *str);
int from_str_ip_only(char *str);
int from_sockaddr(sockaddr *, socklen_t);
char *get_str();
void to_str(char *);
inline u32_t get_type() {
u32_t ret = ((sockaddr *)&inner)->sa_family;
assert(ret == AF_INET || ret == AF_INET6);
return ret;
}
inline u32_t get_len() {
u32_t type = get_type();
switch (type) {
case AF_INET:
return sizeof(sockaddr_in);
case AF_INET6:
return sizeof(sockaddr_in6);
default:
assert(0 == 1);
}
return -1;
}
inline u32_t get_port() {
u32_t type = get_type();
switch (type) {
case AF_INET:
return ntohs(inner.ipv4.sin_port);
case AF_INET6:
return ntohs(inner.ipv6.sin6_port);
default:
assert(0 == 1);
}
return -1;
}
inline void set_port(int port) {
u32_t type = get_type();
switch (type) {
case AF_INET:
inner.ipv4.sin_port = htons(port);
break;
case AF_INET6:
inner.ipv6.sin6_port = htons(port);
break;
default:
assert(0 == 1);
}
return;
}
bool operator==(const address_t &b) const {
// return this->data==b.data;
return memcmp(&this->inner, &b.inner, sizeof(this->inner)) == 0;
}
int new_connected_udp_fd();
char *get_ip();
};
namespace std {
template <>
struct hash<address_t> {
std::size_t operator()(const address_t &key) const {
// return address_t::hash_function(k);
return sdbm((unsigned char *)&key.inner, sizeof(key.inner));
}
};
} // namespace std
union my_ip_t // just a simple version of address_t,stores ip only
{
u32_t v4;
in6_addr v6;
bool equal(const my_ip_t &b) const;
// int from_str(char * str);
char *get_str1() const;
char *get_str2() const;
int from_address_t(address_t a);
};
struct not_copy_able_t {
not_copy_able_t() {
}
not_copy_able_t(const not_copy_able_t &other) {
assert(0 == 1);
}
const not_copy_able_t &operator=(const not_copy_able_t &other) {
assert(0 == 1);
return other;
}
};
const int huge_data_len = 65535 + 100; // a packet with link level header might be larger than 65535
const int huge_buf_len = huge_data_len + 100;
const int max_data_len = 1800;
const int buf_len = max_data_len + 400;
// const int max_address_len=512;
#ifdef UDP2RAW_MP
const int queue_len = 200;
struct queue_t {
char data[queue_len][huge_buf_len];
int data_len[queue_len];
int head = 0;
int tail = 0;
void clear() {
head = tail = 0;
}
int empty() {
if (head == tail)
return 1;
else
return 0;
}
int full() {
if ((tail + 1) % queue_len == head)
return 1;
else
return 0;
}
void peek_front(char *&p, int &len) {
assert(!empty());
p = data[head];
len = data_len[head];
}
void pop_front() {
assert(!empty());
head++;
head %= queue_len;
}
void push_back(char *p, int len) {
assert(!full());
memcpy(data[tail], p, len);
data_len[tail] = len;
tail++;
tail %= queue_len;
}
};
int init_ws();
#endif
u64_t get_current_time();
u64_t pack_u64(u32_t a,u32_t b);
u64_t pack_u64(u32_t a, u32_t b);
u32_t get_u64_h(u64_t a);
u32_t get_u64_l(u64_t a);
char * my_ntoa(u32_t ip);
char *my_ntoa(u32_t ip);
void myexit(int a);
void init_random_number_fd();
u64_t get_true_random_number_64();
u32_t get_true_random_number();
u32_t get_true_random_number_nz();
u64_t ntoh64(u64_t a);
u64_t hton64(u64_t a);
bool larger_than_u16(uint16_t a,uint16_t b);
bool larger_than_u32(u32_t a,u32_t b);
void write_u16(char *, u16_t a); // network order
u16_t read_u16(char *);
void write_u32(char *, u32_t a); // network order
u32_t read_u32(char *);
void write_u64(char *, u64_t a);
u64_t read_u64(char *);
bool larger_than_u16(uint16_t a, uint16_t b);
bool larger_than_u32(u32_t a, u32_t b);
void setnonblocking(int sock);
int set_buf_size(int fd);
unsigned short csum(const unsigned short *ptr,int nbytes);
void signal_handler(int sig);
int numbers_to_char(id_t id1,id_t id2,id_t id3,char * &data,int &len);
int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3);
int set_buf_size(int fd, int socket_buf_size);
void myexit(int a);
int add_iptables_rule(char *);
unsigned short csum(const unsigned short *ptr, int nbytes);
unsigned short csum_with_header(char *header, int hlen, const unsigned short *ptr, int nbytes);
int clear_iptables_rule();
int numbers_to_char(my_id_t id1, my_id_t id2, my_id_t id3, char *&data, int &len);
int char_to_numbers(const char *data, int len, my_id_t &id1, my_id_t &id2, my_id_t &id3);
const int show_none = 0;
const int show_command = 0x1;
const int show_log = 0x2;
const int show_all = show_command | show_log;
int run_command(string command, char *&output, int flag = show_all);
// int run_command_no_log(string command,char * &output);
int read_file(const char *file, string &output);
vector<string> string_to_vec(const char *s, const char *sp);
vector<vector<string> > string_to_vec2(const char *s);
string trim(const string &str, char c);
string trim_conf_line(const string &str);
vector<string> parse_conf_line(const string &s);
int hex_to_u32_with_endian(const string &a, u32_t &output);
int hex_to_u32(const string &a, u32_t &output);
// extern string iptables_pattern;
int create_fifo(char *file);
void print_binary_chars(const char *a, int len);
template <class key_t>
struct lru_collector_t : not_copy_able_t {
// typedef void* key_t;
//#define key_t void*
struct lru_pair_t {
key_t key;
my_time_t ts;
};
unordered_map<key_t, typename list<lru_pair_t>::iterator> mp;
list<lru_pair_t> q;
int update(key_t key) {
assert(mp.find(key) != mp.end());
auto it = mp[key];
q.erase(it);
my_time_t value = get_current_time();
if (!q.empty()) {
assert(value >= q.front().ts);
}
lru_pair_t tmp;
tmp.key = key;
tmp.ts = value;
q.push_front(tmp);
mp[key] = q.begin();
return 0;
}
int new_key(key_t key) {
assert(mp.find(key) == mp.end());
my_time_t value = get_current_time();
if (!q.empty()) {
assert(value >= q.front().ts);
}
lru_pair_t tmp;
tmp.key = key;
tmp.ts = value;
q.push_front(tmp);
mp[key] = q.begin();
return 0;
}
int size() {
return q.size();
}
int empty() {
return q.empty();
}
void clear() {
mp.clear();
q.clear();
}
my_time_t ts_of(key_t key) {
assert(mp.find(key) != mp.end());
return mp[key]->ts;
}
my_time_t peek_back(key_t &key) {
assert(!q.empty());
auto it = q.end();
it--;
key = it->key;
return it->ts;
}
void erase(key_t key) {
assert(mp.find(key) != mp.end());
q.erase(mp[key]);
mp.erase(key);
}
/*
void erase_back()
{
assert(!q.empty());
auto it=q.end(); it--;
key_t key=it->key;
erase(key);
}*/
};
#endif /* COMMON_H_ */

657
connection.cpp Normal file
View File

@ -0,0 +1,657 @@
/*
* connection.cpp
*
* Created on: Sep 23, 2017
* Author: root
*/
#include "connection.h"
#include "encrypt.h"
#include "fd_manager.h"
int disable_anti_replay = 0; // if anti_replay windows is diabled
const int disable_conn_clear = 0; // a raw connection is called conn.
conn_manager_t conn_manager;
anti_replay_seq_t anti_replay_t::get_new_seq_for_send() {
return anti_replay_seq++;
}
anti_replay_t::anti_replay_t() {
max_packet_received = 0;
anti_replay_seq = get_true_random_number_64() / 10; // random first seq
// memset(window,0,sizeof(window)); //not necessary
}
void anti_replay_t::re_init() {
max_packet_received = 0;
// memset(window,0,sizeof(window));
}
int anti_replay_t::is_vaild(u64_t seq) {
if (disable_anti_replay) return 1;
// if(disabled) return 0;
if (seq == max_packet_received)
return 0;
else if (seq > max_packet_received) {
if (seq - max_packet_received >= anti_replay_window_size) {
memset(window, 0, sizeof(window));
window[seq % anti_replay_window_size] = 1;
} else {
for (u64_t i = max_packet_received + 1; i < seq; i++)
window[i % anti_replay_window_size] = 0;
window[seq % anti_replay_window_size] = 1;
}
max_packet_received = seq;
return 1;
} else if (seq < max_packet_received) {
if (max_packet_received - seq >= anti_replay_window_size)
return 0;
else {
if (window[seq % anti_replay_window_size] == 1)
return 0;
else {
window[seq % anti_replay_window_size] = 1;
return 1;
}
}
}
return 0; // for complier check
}
void conn_info_t::recover(const conn_info_t &conn_info) {
raw_info = conn_info.raw_info;
raw_info.rst_received = 0;
raw_info.disabled = 0;
last_state_time = conn_info.last_state_time;
last_hb_recv_time = conn_info.last_hb_recv_time;
last_hb_sent_time = conn_info.last_hb_sent_time;
my_id = conn_info.my_id;
oppsite_id = conn_info.oppsite_id;
blob->anti_replay.re_init();
my_roller = 0; // no need to set,but for easier debug,set it to zero
oppsite_roller = 0; // same as above
last_oppsite_roller_time = 0;
}
void conn_info_t::re_init() {
// send_packet_info.protocol=g_packet_info_send.protocol;
if (program_mode == server_mode)
state.server_current_state = server_idle;
else
state.client_current_state = client_idle;
last_state_time = 0;
oppsite_const_id = 0;
timer_fd64 = 0;
my_roller = 0;
oppsite_roller = 0;
last_oppsite_roller_time = 0;
}
conn_info_t::conn_info_t() {
blob = 0;
re_init();
}
void conn_info_t::prepare() {
assert(blob == 0);
blob = new blob_t;
if (program_mode == server_mode) {
blob->conv_manager.s.additional_clear_function = server_clear_function;
} else {
assert(program_mode == client_mode);
}
}
conn_info_t::conn_info_t(const conn_info_t &b) {
assert(0 == 1);
// mylog(log_error,"called!!!!!!!!!!!!!\n");
}
conn_info_t &conn_info_t::operator=(const conn_info_t &b) {
mylog(log_fatal, "not allowed\n");
myexit(-1);
return *this;
}
conn_info_t::~conn_info_t() {
if (program_mode == server_mode) {
if (state.server_current_state == server_ready) {
assert(blob != 0);
assert(oppsite_const_id != 0);
// assert(conn_manager.const_id_mp.find(oppsite_const_id)!=conn_manager.const_id_mp.end()); // conn_manager 's deconstuction function erases it
} else {
assert(blob == 0);
assert(oppsite_const_id == 0);
}
}
assert(timer_fd64 == 0);
// if(oppsite_const_id!=0) //do this at conn_manager 's deconstuction function
// conn_manager.const_id_mp.erase(oppsite_const_id);
if (blob != 0)
delete blob;
// send_packet_info.protocol=g_packet_info_send.protocol;
}
conn_manager_t::conn_manager_t() {
ready_num = 0;
mp.reserve(10007);
// clear_it=mp.begin();
// timer_fd_mp.reserve(10007);
const_id_mp.reserve(10007);
// udp_fd_mp.reserve(100007);
last_clear_time = 0;
// current_ready_ip=0;
// current_ready_port=0;
}
int conn_manager_t::exist(address_t addr) {
// u64_t u64=0;
// u64=ip;
// u64<<=32u;
// u64|=port;
if (mp.find(addr) != mp.end()) {
return 1;
}
return 0;
}
/*
int insert(uint32_t ip,uint16_t port)
{
uint64_t u64=0;
u64=ip;
u64<<=32u;
u64|=port;
mp[u64];
return 0;
}*/
conn_info_t *&conn_manager_t::find_insert_p(address_t addr) // be aware,the adress may change after rehash
{
// u64_t u64=0;
// u64=ip;
// u64<<=32u;
// u64|=port;
unordered_map<address_t, conn_info_t *>::iterator it = mp.find(addr);
if (it == mp.end()) {
mp[addr] = new conn_info_t;
// lru.new_key(addr);
} else {
// lru.update(addr);
}
return mp[addr];
}
conn_info_t &conn_manager_t::find_insert(address_t addr) // be aware,the adress may change after rehash
{
// u64_t u64=0;
// u64=ip;
// u64<<=32u;
// u64|=port;
unordered_map<address_t, conn_info_t *>::iterator it = mp.find(addr);
if (it == mp.end()) {
mp[addr] = new conn_info_t;
// lru.new_key(addr);
} else {
// lru.update(addr);
}
return *mp[addr];
}
int conn_manager_t::erase(unordered_map<address_t, conn_info_t *>::iterator erase_it) {
if (erase_it->second->state.server_current_state == server_ready) {
ready_num--;
assert(i32_t(ready_num) != -1);
assert(erase_it->second != 0);
assert(erase_it->second->timer_fd64 != 0);
assert(fd_manager.exist(erase_it->second->timer_fd64));
assert(erase_it->second->oppsite_const_id != 0);
assert(const_id_mp.find(erase_it->second->oppsite_const_id) != const_id_mp.end());
// assert(timer_fd_mp.find(erase_it->second->timer_fd)!=timer_fd_mp.end());
const_id_mp.erase(erase_it->second->oppsite_const_id);
fd_manager.fd64_close(erase_it->second->timer_fd64);
erase_it->second->timer_fd64 = 0;
// timer_fd_mp.erase(erase_it->second->timer_fd);
// close(erase_it->second->timer_fd);// close will auto delte it from epoll
delete (erase_it->second);
mp.erase(erase_it->first);
} else {
assert(erase_it->second->blob == 0);
assert(erase_it->second->timer_fd64 == 0);
assert(erase_it->second->oppsite_const_id == 0);
delete (erase_it->second);
mp.erase(erase_it->first);
}
return 0;
}
int conn_manager_t::clear_inactive() {
if (get_current_time() - last_clear_time > conn_clear_interval) {
last_clear_time = get_current_time();
return clear_inactive0();
}
return 0;
}
int conn_manager_t::clear_inactive0() {
unordered_map<address_t, conn_info_t *>::iterator it;
unordered_map<address_t, conn_info_t *>::iterator old_it;
if (disable_conn_clear) return 0;
// map<uint32_t,uint64_t>::iterator it;
int cnt = 0;
it = clear_it;
int size = mp.size();
int num_to_clean = size / conn_clear_ratio + conn_clear_min; // clear 1/10 each time,to avoid latency glitch
mylog(log_trace, "mp.size() %d\n", size);
num_to_clean = min(num_to_clean, (int)mp.size());
u64_t current_time = get_current_time();
for (;;) {
if (cnt >= num_to_clean) break;
if (mp.begin() == mp.end()) break;
if (it == mp.end()) {
it = mp.begin();
}
if (it->second->state.server_current_state == server_ready && current_time - it->second->last_hb_recv_time <= server_conn_timeout) {
it++;
} else if (it->second->state.server_current_state != server_ready && current_time - it->second->last_state_time <= server_handshake_timeout) {
it++;
} else if (it->second->blob != 0 && it->second->blob->conv_manager.s.get_size() > 0) {
assert(it->second->state.server_current_state == server_ready);
it++;
} else {
mylog(log_info, "[%s:%d]inactive conn cleared \n", it->second->raw_info.recv_info.new_src_ip.get_str1(), it->second->raw_info.recv_info.src_port);
old_it = it;
it++;
erase(old_it);
}
cnt++;
}
clear_it = it;
return 0;
}
int send_bare(raw_info_t &raw_info, const char *data, int len) // send function with encryption but no anti replay,this is used when client and server verifys each other
// you have to design the protocol carefully, so that you wont be affect by relay attack
{
if (len < 0) {
mylog(log_debug, "input_len <0\n");
return -1;
}
packet_info_t &send_info = raw_info.send_info;
packet_info_t &recv_info = raw_info.recv_info;
char send_data_buf[buf_len]; // buf for send data and send hb
char send_data_buf2[buf_len];
// static send_bare[buf_len];
iv_t iv = get_true_random_number_64();
padding_t padding = get_true_random_number_64();
memcpy(send_data_buf, &iv, sizeof(iv));
memcpy(send_data_buf + sizeof(iv), &padding, sizeof(padding));
send_data_buf[sizeof(iv) + sizeof(padding)] = 'b';
memcpy(send_data_buf + sizeof(iv) + sizeof(padding) + 1, data, len);
int new_len = len + sizeof(iv) + sizeof(padding) + 1;
if (my_encrypt(send_data_buf, send_data_buf2, new_len) != 0) {
return -1;
}
send_raw0(raw_info, send_data_buf2, new_len);
return 0;
}
int reserved_parse_bare(const char *input, int input_len, char *&data, int &len) // a sub function used in recv_bare
{
static char recv_data_buf[buf_len];
if (input_len < 0) {
mylog(log_debug, "input_len <0\n");
return -1;
}
if (my_decrypt(input, recv_data_buf, input_len) != 0) {
mylog(log_debug, "decrypt_fail in recv bare\n");
return -1;
}
if (recv_data_buf[sizeof(iv_t) + sizeof(padding_t)] != 'b') {
mylog(log_debug, "not a bare packet\n");
return -1;
}
len = input_len;
data = recv_data_buf + sizeof(iv_t) + sizeof(padding_t) + 1;
len -= sizeof(iv_t) + sizeof(padding_t) + 1;
if (len < 0) {
mylog(log_debug, "len <0\n");
return -1;
}
return 0;
}
int recv_bare(raw_info_t &raw_info, char *&data, int &len) // recv function with encryption but no anti replay,this is used when client and server verifys each other
// you have to design the protocol carefully, so that you wont be affect by relay attack
{
packet_info_t &send_info = raw_info.send_info;
packet_info_t &recv_info = raw_info.recv_info;
if (recv_raw0(raw_info, data, len) < 0) {
// printf("recv_raw_fail in recv bare\n");
return -1;
}
if (len >= max_data_len + 1) {
mylog(log_debug, "data_len=%d >= max_data_len+1,ignored", len);
return -1;
}
mylog(log_trace, "data len=%d\n", len);
if ((raw_mode == mode_faketcp && (recv_info.syn == 1 || recv_info.ack != 1))) {
mylog(log_debug, "unexpect packet type recv_info.syn=%d recv_info.ack=%d \n", recv_info.syn, recv_info.ack);
return -1;
}
return reserved_parse_bare(data, len, data, len);
}
int send_handshake(raw_info_t &raw_info, my_id_t id1, my_id_t id2, my_id_t id3) // a warp for send_bare for sending handshake(this is not tcp handshake) easily
{
packet_info_t &send_info = raw_info.send_info;
packet_info_t &recv_info = raw_info.recv_info;
char *data;
int len;
// len=sizeof(id_t)*3;
if (numbers_to_char(id1, id2, id3, data, len) != 0) return -1;
if (send_bare(raw_info, data, len) != 0) {
mylog(log_warn, "send bare fail\n");
return -1;
}
return 0;
}
/*
int recv_handshake(packet_info_t &info,id_t &id1,id_t &id2,id_t &id3)
{
char * data;int len;
if(recv_bare(info,data,len)!=0) return -1;
if(char_to_numbers(data,len,id1,id2,id3)!=0) return -1;
return 0;
}*/
int send_safer(conn_info_t &conn_info, char type, const char *data, int len) // safer transfer function with anti-replay,when mutually verification is done.
{
packet_info_t &send_info = conn_info.raw_info.send_info;
packet_info_t &recv_info = conn_info.raw_info.recv_info;
if (type != 'h' && type != 'd') {
mylog(log_warn, "first byte is not h or d ,%x\n", type);
return -1;
}
char send_data_buf[buf_len]; // buf for send data and send hb
char send_data_buf2[buf_len];
my_id_t n_tmp_id = htonl(conn_info.my_id);
memcpy(send_data_buf, &n_tmp_id, sizeof(n_tmp_id));
n_tmp_id = htonl(conn_info.oppsite_id);
memcpy(send_data_buf + sizeof(n_tmp_id), &n_tmp_id, sizeof(n_tmp_id));
anti_replay_seq_t n_seq = hton64(conn_info.blob->anti_replay.get_new_seq_for_send());
memcpy(send_data_buf + sizeof(n_tmp_id) * 2, &n_seq, sizeof(n_seq));
send_data_buf[sizeof(n_tmp_id) * 2 + sizeof(n_seq)] = type;
send_data_buf[sizeof(n_tmp_id) * 2 + sizeof(n_seq) + 1] = conn_info.my_roller;
memcpy(send_data_buf + 2 + sizeof(n_tmp_id) * 2 + sizeof(n_seq), data, len); // data;
int new_len = len + sizeof(n_seq) + sizeof(n_tmp_id) * 2 + 2;
if (g_fix_gro == 0) {
if (my_encrypt(send_data_buf, send_data_buf2, new_len) != 0) {
return -1;
}
} else {
if (my_encrypt(send_data_buf, send_data_buf2 + 2, new_len) != 0) {
return -1;
}
write_u16(send_data_buf2, new_len);
new_len += 2;
if (cipher_mode == cipher_xor) {
send_data_buf2[0] ^= gro_xor[0];
send_data_buf2[1] ^= gro_xor[1];
} else if (cipher_mode == cipher_aes128cbc || cipher_mode == cipher_aes128cfb) {
aes_ecb_encrypt1(send_data_buf2);
}
}
if (send_raw0(conn_info.raw_info, send_data_buf2, new_len) != 0) return -1;
if (after_send_raw0(conn_info.raw_info) != 0) return -1;
return 0;
}
int send_data_safer(conn_info_t &conn_info, const char *data, int len, u32_t conv_num) // a wrap for send_safer for transfer data.
{
packet_info_t &send_info = conn_info.raw_info.send_info;
packet_info_t &recv_info = conn_info.raw_info.recv_info;
char send_data_buf[buf_len];
// send_data_buf[0]='d';
u32_t n_conv_num = htonl(conv_num);
memcpy(send_data_buf, &n_conv_num, sizeof(n_conv_num));
memcpy(send_data_buf + sizeof(n_conv_num), data, len);
int new_len = len + sizeof(n_conv_num);
send_safer(conn_info, 'd', send_data_buf, new_len);
return 0;
}
int reserved_parse_safer(conn_info_t &conn_info, const char *input, int input_len, char &type, char *&data, int &len) // subfunction for recv_safer,allow overlap
{
static char recv_data_buf[buf_len];
// char *recv_data_buf=recv_data_buf0; //fix strict alias warning
if (my_decrypt(input, recv_data_buf, input_len) != 0) {
// printf("decrypt fail\n");
return -1;
}
// char *a=recv_data_buf;
// id_t h_oppiste_id= ntohl ( *((id_t * )(recv_data_buf)) );
my_id_t h_oppsite_id;
memcpy(&h_oppsite_id, recv_data_buf, sizeof(h_oppsite_id));
h_oppsite_id = ntohl(h_oppsite_id);
// id_t h_my_id= ntohl ( *((id_t * )(recv_data_buf+sizeof(id_t))) );
my_id_t h_my_id;
memcpy(&h_my_id, recv_data_buf + sizeof(my_id_t), sizeof(h_my_id));
h_my_id = ntohl(h_my_id);
// anti_replay_seq_t h_seq= ntoh64 ( *((anti_replay_seq_t * )(recv_data_buf +sizeof(id_t) *2 )) );
anti_replay_seq_t h_seq;
memcpy(&h_seq, recv_data_buf + sizeof(my_id_t) * 2, sizeof(h_seq));
h_seq = ntoh64(h_seq);
if (h_oppsite_id != conn_info.oppsite_id || h_my_id != conn_info.my_id) {
mylog(log_debug, "id and oppsite_id verification failed %x %x %x %x \n", h_oppsite_id, conn_info.oppsite_id, h_my_id, conn_info.my_id);
return -1;
}
if (conn_info.blob->anti_replay.is_vaild(h_seq) != 1) {
mylog(log_debug, "dropped replay packet\n");
return -1;
}
// printf("recv _len %d\n ",recv_len);
data = recv_data_buf + sizeof(anti_replay_seq_t) + sizeof(my_id_t) * 2;
len = input_len - (sizeof(anti_replay_seq_t) + sizeof(my_id_t) * 2);
if (data[0] != 'h' && data[0] != 'd') {
mylog(log_debug, "first byte is not h or d ,%x\n", data[0]);
return -1;
}
uint8_t roller = data[1];
type = data[0];
data += 2;
len -= 2;
if (len < 0) {
mylog(log_debug, "len <0 ,%d\n", len);
return -1;
}
if (roller != conn_info.oppsite_roller) {
conn_info.oppsite_roller = roller;
conn_info.last_oppsite_roller_time = get_current_time();
}
if (hb_mode == 0)
conn_info.my_roller++; // increase on a successful recv
else if (hb_mode == 1) {
if (type == 'h')
conn_info.my_roller++;
} else {
mylog(log_fatal, "unknow hb_mode\n");
myexit(-1);
}
if (after_recv_raw0(conn_info.raw_info) != 0) return -1; // TODO might need to move this function to somewhere else after --fix-gro is introduced
return 0;
}
int recv_safer_notused(conn_info_t &conn_info, char &type, char *&data, int &len) /// safer transfer function with anti-replay,when mutually verification is done.
{
packet_info_t &send_info = conn_info.raw_info.send_info;
packet_info_t &recv_info = conn_info.raw_info.recv_info;
char *recv_data;
int recv_len;
// static char recv_data_buf[buf_len];
if (recv_raw0(conn_info.raw_info, recv_data, recv_len) != 0) return -1;
return reserved_parse_safer(conn_info, recv_data, recv_len, type, data, len);
}
int recv_safer_multi(conn_info_t &conn_info, vector<char> &type_arr, vector<string> &data_arr) /// safer transfer function with anti-replay,when mutually verification is done.
{
packet_info_t &send_info = conn_info.raw_info.send_info;
packet_info_t &recv_info = conn_info.raw_info.recv_info;
char *recv_data;
int recv_len;
assert(type_arr.empty());
assert(data_arr.empty());
if (recv_raw0(conn_info.raw_info, recv_data, recv_len) != 0) return -1;
char type;
char *data;
int len;
if (g_fix_gro == 0) {
int ret = reserved_parse_safer(conn_info, recv_data, recv_len, type, data, len);
if (ret == 0) {
type_arr.push_back(type);
data_arr.emplace_back(data, data + len);
// std::copy(data,data+len,data_arr[0]);
}
return 0;
} else {
char *ori_recv_data = recv_data;
int ori_recv_len = recv_len;
// mylog(log_debug,"recv_len:%d\n",recv_len);
int cnt = 0;
while (recv_len >= 16) {
cnt++;
int single_len_no_xor;
single_len_no_xor = read_u16(recv_data);
int single_len;
if (cipher_mode == cipher_xor) {
recv_data[0] ^= gro_xor[0];
recv_data[1] ^= gro_xor[1];
} else if (cipher_mode == cipher_aes128cbc || cipher_mode == cipher_aes128cfb) {
aes_ecb_decrypt1(recv_data);
}
single_len = read_u16(recv_data);
recv_len -= 2;
recv_data += 2;
if (single_len > recv_len) {
mylog(log_debug, "illegal single_len %d(%d), recv_len %d left,dropped\n", single_len, single_len_no_xor, recv_len);
break;
}
if (single_len > max_data_len) {
mylog(log_warn, "single_len %d(%d) > %d, maybe you need to turn down mtu at upper level\n", single_len, single_len_no_xor, max_data_len);
break;
}
int ret = reserved_parse_safer(conn_info, recv_data, single_len, type, data, len);
if (ret != 0) {
mylog(log_debug, "parse failed, offset= %d,single_len=%d(%d)\n", (int)(recv_data - ori_recv_data), single_len, single_len_no_xor);
} else {
type_arr.push_back(type);
data_arr.emplace_back(data, data + len);
// std::copy(data,data+len,data_arr[data_arr.size()-1]);
}
recv_data += single_len;
recv_len -= single_len;
}
if (cnt > 1) {
mylog(log_debug, "got a suspected gro packet, %d packets recovered, recv_len=%d, loop_cnt=%d\n", (int)data_arr.size(), ori_recv_len, cnt);
}
return 0;
}
}
void server_clear_function(u64_t u64) // used in conv_manager in server mode.for server we have to use one udp fd for one conv(udp connection),
// so we have to close the fd when conv expires
{
// int fd=int(u64);
// int ret;
// assert(fd!=0);
/*
epoll_event ev;
ev.events = EPOLLIN;
ev.data.u64 = u64;
ret = epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &ev);
if (ret!=0)
{
mylog(log_fatal,"fd:%d epoll delete failed!!!!\n",fd);
myexit(-1); //this shouldnt happen
}*/
// no need
/*ret= close(fd); //closed fd should be auto removed from epoll
if (ret!=0)
{
mylog(log_fatal,"close fd %d failed !!!!\n",fd);
myexit(-1); //this shouldnt happen
}*/
// mylog(log_fatal,"size:%d !!!!\n",conn_manager.udp_fd_mp.size());
fd64_t fd64 = u64;
assert(fd_manager.exist(fd64));
fd_manager.fd64_close(fd64);
// assert(conn_manager.udp_fd_mp.find(fd)!=conn_manager.udp_fd_mp.end());
// conn_manager.udp_fd_mp.erase(fd);
}

313
connection.h Normal file
View File

@ -0,0 +1,313 @@
/*
* connection.h
*
* Created on: Sep 23, 2017
* Author: root
*/
#ifndef CONNECTION_H_
#define CONNECTION_H_
extern int disable_anti_replay;
#include "connection.h"
#include "common.h"
#include "log.h"
#include "network.h"
#include "misc.h"
const int disable_conv_clear = 0; // a udp connection in the multiplexer is called conversation in this program,conv for short.
struct anti_replay_t // its for anti replay attack,similar to openvpn/ipsec 's anti replay window
{
u64_t max_packet_received;
char window[anti_replay_window_size];
anti_replay_seq_t anti_replay_seq;
anti_replay_seq_t get_new_seq_for_send();
anti_replay_t();
void re_init();
int is_vaild(u64_t seq);
}; // anti_replay;
void server_clear_function(u64_t u64);
#include <type_traits>
template <class T>
struct conv_manager_t // manage the udp connections
{
// typedef hash_map map;
unordered_map<T, u32_t> data_to_conv; // conv and u64 are both supposed to be uniq
unordered_map<u32_t, T> conv_to_data;
lru_collector_t<u32_t> lru;
// unordered_map<u32_t,u64_t> conv_last_active_time;
// unordered_map<u32_t,u64_t>::iterator clear_it;
void (*additional_clear_function)(T data) = 0;
long long last_clear_time;
conv_manager_t() {
// clear_it=conv_last_active_time.begin();
long long last_clear_time = 0;
additional_clear_function = 0;
}
~conv_manager_t() {
clear();
}
int get_size() {
return conv_to_data.size();
}
void reserve() {
data_to_conv.reserve(10007);
conv_to_data.reserve(10007);
// conv_last_active_time.reserve(10007);
lru.mp.reserve(10007);
}
void clear() {
if (disable_conv_clear) return;
if (additional_clear_function != 0) {
for (auto it = conv_to_data.begin(); it != conv_to_data.end(); it++) {
// int fd=int((it->second<<32u)>>32u);
additional_clear_function(it->second);
}
}
data_to_conv.clear();
conv_to_data.clear();
lru.clear();
// conv_last_active_time.clear();
// clear_it=conv_last_active_time.begin();
}
u32_t get_new_conv() {
u32_t conv = get_true_random_number_nz();
while (conv_to_data.find(conv) != conv_to_data.end()) {
conv = get_true_random_number_nz();
}
return conv;
}
int is_conv_used(u32_t conv) {
return conv_to_data.find(conv) != conv_to_data.end();
}
int is_data_used(T data) {
return data_to_conv.find(data) != data_to_conv.end();
}
u32_t find_conv_by_data(T data) {
return data_to_conv[data];
}
T find_data_by_conv(u32_t conv) {
return conv_to_data[conv];
}
int update_active_time(u32_t conv) {
// return conv_last_active_time[conv]=get_current_time();
lru.update(conv);
return 0;
}
int insert_conv(u32_t conv, T data) {
data_to_conv[data] = conv;
conv_to_data[conv] = data;
// conv_last_active_time[conv]=get_current_time();
lru.new_key(conv);
return 0;
}
int erase_conv(u32_t conv) {
if (disable_conv_clear) return 0;
T data = conv_to_data[conv];
if (additional_clear_function != 0) {
additional_clear_function(data);
}
conv_to_data.erase(conv);
data_to_conv.erase(data);
// conv_last_active_time.erase(conv);
lru.erase(conv);
return 0;
}
int clear_inactive(char *info = 0) {
if (get_current_time() - last_clear_time > conv_clear_interval) {
last_clear_time = get_current_time();
return clear_inactive0(info);
}
return 0;
}
int clear_inactive0(char *info) {
if (disable_conv_clear) return 0;
unordered_map<u32_t, u64_t>::iterator it;
unordered_map<u32_t, u64_t>::iterator old_it;
// map<uint32_t,uint64_t>::iterator it;
int cnt = 0;
// it=clear_it;
int size = lru.size();
int num_to_clean = size / conv_clear_ratio + conv_clear_min; // clear 1/10 each time,to avoid latency glitch
num_to_clean = min(num_to_clean, size);
my_time_t current_time = get_current_time();
for (;;) {
if (cnt >= num_to_clean) break;
if (lru.empty()) break;
u32_t conv;
my_time_t ts = lru.peek_back(conv);
if (current_time - ts < conv_timeout) break;
erase_conv(conv);
if (info == 0) {
mylog(log_info, "conv %x cleared\n", conv);
} else {
mylog(log_info, "[%s]conv %x cleared\n", info, conv);
}
cnt++;
}
return 0;
}
/*
conv_manager_t();
~conv_manager_t();
int get_size();
void reserve();
void clear();
u32_t get_new_conv();
int is_conv_used(u32_t conv);
int is_u64_used(T u64);
u32_t find_conv_by_u64(T u64);
T find_u64_by_conv(u32_t conv);
int update_active_time(u32_t conv);
int insert_conv(u32_t conv,T u64);
int erase_conv(u32_t conv);
int clear_inactive(char * ip_port=0);
int clear_inactive0(char * ip_port);*/
}; // g_conv_manager;
struct blob_t : not_copy_able_t // used in conn_info_t.
{
union tmp_union_t // conv_manager_t is here to avoid copying when a connection is recovered
{
conv_manager_t<address_t> c;
conv_manager_t<u64_t> s;
// avoid templates here and there, avoid pointer and type cast
tmp_union_t() {
if (program_mode == client_mode) {
new (&c) conv_manager_t<address_t>();
} else {
assert(program_mode == server_mode);
new (&s) conv_manager_t<u64_t>();
}
}
~tmp_union_t() {
if (program_mode == client_mode) {
c.~conv_manager_t<address_t>();
} else {
assert(program_mode == server_mode);
s.~conv_manager_t<u64_t>();
}
}
} conv_manager;
anti_replay_t anti_replay; // anti_replay_t is here bc its huge,its allocation is delayed.
};
struct conn_info_t // stores info for a raw connection.for client ,there is only one connection,for server there can be thousand of connection since server can
// handle multiple clients
{
current_state_t state;
raw_info_t raw_info;
u64_t last_state_time;
u64_t last_hb_sent_time; // client re-use this for retry
u64_t last_hb_recv_time;
// long long last_resent_time;
my_id_t my_id;
my_id_t oppsite_id;
fd64_t timer_fd64;
fd64_t udp_fd64;
my_id_t oppsite_const_id;
blob_t *blob;
uint8_t my_roller;
uint8_t oppsite_roller;
u64_t last_oppsite_roller_time;
// ip_port_t ip_port;
/*
const uint32_t &ip=raw_info.recv_info.src_ip;
const uint16_t &port=raw_info.recv_info.src_port;
*/
void recover(const conn_info_t &conn_info);
void re_init();
conn_info_t();
void prepare();
conn_info_t(const conn_info_t &b);
conn_info_t &operator=(const conn_info_t &b);
~conn_info_t();
}; // g_conn_info;
struct conn_manager_t // manager for connections. for client,we dont need conn_manager since there is only one connection.for server we use one conn_manager for all connections
{
u32_t ready_num;
// unordered_map<int,conn_info_t *> udp_fd_mp; //a bit dirty to used pointer,but can void unordered_map search
// unordered_map<int,conn_info_t *> timer_fd_mp;//we can use pointer here since unordered_map.rehash() uses shallow copy
unordered_map<my_id_t, conn_info_t *> const_id_mp;
unordered_map<address_t, conn_info_t *> mp; // put it at end so that it de-consturcts first
// lru_collector_t<address_t> lru;
unordered_map<address_t, conn_info_t *>::iterator clear_it;
long long last_clear_time;
conn_manager_t();
int exist(address_t addr);
/*
int insert(uint32_t ip,uint16_t port)
{
uint64_t u64=0;
u64=ip;
u64<<=32u;
u64|=port;
mp[u64];
return 0;
}*/
conn_info_t *&find_insert_p(address_t addr); // be aware,the adress may change after rehash //not true?
conn_info_t &find_insert(address_t addr); // be aware,the adress may change after rehash
int erase(unordered_map<address_t, conn_info_t *>::iterator erase_it);
int clear_inactive();
int clear_inactive0();
};
extern conn_manager_t conn_manager;
void server_clear_function(u64_t u64);
int send_bare(raw_info_t &raw_info, const char *data, int len); // send function with encryption but no anti replay,this is used when client and server verifys each other
// you have to design the protocol carefully, so that you wont be affect by relay attack
// int reserved_parse_bare(const char *input,int input_len,char* & data,int & len); // a sub function used in recv_bare
int recv_bare(raw_info_t &raw_info, char *&data, int &len); // recv function with encryption but no anti replay,this is used when client and server verifys each other
// you have to design the protocol carefully, so that you wont be affect by relay attack
int send_handshake(raw_info_t &raw_info, my_id_t id1, my_id_t id2, my_id_t id3); // a warp for send_bare for sending handshake(this is not tcp handshake) easily
int send_safer(conn_info_t &conn_info, char type, const char *data, int len); // safer transfer function with anti-replay,when mutually verification is done.
int send_data_safer(conn_info_t &conn_info, const char *data, int len, u32_t conv_num); // a wrap for send_safer for transfer data.
// int reserved_parse_safer(conn_info_t &conn_info,const char * input,int input_len,char &type,char* &data,int &len);//subfunction for recv_safer,allow overlap
// int recv_safer(conn_info_t &conn_info,char &type,char* &data,int &len);///safer transfer function with anti-replay,when mutually verification is done.
int recv_safer_multi(conn_info_t &conn_info, vector<char> &type_arr, vector<string> &data_arr); // new api for handle gro
#endif /* CONNECTION_H_ */

271
doc/README.zh-cn.md Normal file
View File

@ -0,0 +1,271 @@
# Udp2raw-tunnel
![image2](/images/image0.PNG)
udp2raw tunnel通过raw socket给UDP包加上TCP或ICMP header进而绕过UDP屏蔽或QoS或在UDP不稳定的环境下提升稳定性。可以有效防止在使用kcptun或者finalspeed的情况下udp端口被运营商限速。
支持心跳保活、自动重连,重连后会恢复上次连接,在底层掉线的情况下可以保持上层不掉线。同时有加密、防重放攻击、信道复用的功能。
[English](/README.md)
[udp2raw+kcptun step_by_step教程](kcptun_step_by_step.md)
[udp2raw+finalspeed step_by_step教程](finalspeed_step_by_step.md)
[udp2raw wiki](https://github.com/wangyu-/udp2raw-tunnel/wiki)
**提示:**
udp2raw不是加速器只是一个帮助你绕过UDP限制的工具。如果你需要UDP“加速器” (改善UDP丢包)请看UDPspeeder。
UDPspeeder的repo:
https://github.com/wangyu-/UDPspeeder
# 支持的平台
Linux主机有root权限或cap_net_raw capability.。可以是PC、android手机/平板、openwrt路由器、树莓派。主机上最好安装了iptables命令(apt/yum很容易安装)。
Release中提供了`amd64``x86``arm``mips_be``mips_le`的预编译binary.
##### 对于windows和mac用户
可以用[这个repo](https://github.com/wangyu-/udp2raw-multiplatform)里的udp2raw。
##### 对于ios和游戏主机用户
可以把udp2raw运行在局域网的其他机器/虚拟机上。最好的办法是买个能刷OpenWrt/LEDE/梅林的路由器把udp2raw运行在路由器上。
# 功能特性
### 把udp流量伪装成tcp /icmp
用raw socket给udp包加上tcp/icmp包头可以突破udp流量限制或Udp QOS。或者在udp nat有问题的环境下提升稳定性。  另外也支持用raw 发udp包这样流量不会被伪装只会被加密。
### 模拟TCP3次握手
模拟TCP3次握手模拟seq ack过程。另外还模拟了一些tcp optionMSS,sackOk,TS,TS_ack,wscale用来使流量看起来更像是由普通的linux tcp协议栈发送的。
### 心跳保活、自动重连,连接恢复
心跳保活、自动重连udp2raw重连可以恢复上次的连接重连后上层连接继续有效底层掉线上层不掉线。有效解决上层连接断开的问题。 (功能借鉴自[kcptun-raw](https://github.com/Chion82/kcptun-raw)**就算你拔掉网线重插或者重新拨号获得新ip上层应用也不会断线**
### 加密、防重放攻击
用aes128cbc加密(或更弱的xor)hmac-sha1(或更弱的md5/crc32/simple)做数据完整校验。用类似ipsec/openvpn的replay window机制来防止重放攻击。
[Notes on encryption](https://github.com/wangyu-/udp2raw-tunnel/wiki/Notes-on-encryption)
### 其他特性
信道复用client的udp端支持多个连接。
server支持多个client也能正确处理多个连接的重连和连接恢复。
NAT 穿透 tcp icmp udp模式都支持nat穿透。
支持Openvz配合finalspeed使用可以在openvz上用tcp模式的finalspeed.
支持Openwrt没有编译依赖容易编译到任何平台上。
### 关键词
突破udp qos,突破udp屏蔽openvpn tcp over tcp problem,openvpn over icmp,udp to icmp tunnel,udp to tcp tunnel,udp via icmp,udp via tcp
# 简明操作说明
### 安装
下载编译好的二进制文件,解压到任意目录。
https://github.com/wangyu-/udp2raw-tunnel/releases
### 运行
假设你有一个serverip为44.55.66.77有一个服务监听在udp 7777端口。 假设你本地的主机到44.55.66.77的UDP流量被屏蔽了或者被qos了
```
在server端运行:
./udp2raw_amd64 -s -l0.0.0.0:4096 -r127.0.0.1:7777 -k "passwd" --raw-mode faketcp --cipher-mode xor -a
在client端运行:
./udp2raw_amd64 -c -l0.0.0.0:3333 -r44.55.66.77:4096 -k "passwd" --raw-mode faketcp --cipher-mode xor -a
```
(以上例子需要用root账号运行。 用非root运行udp2raw需要一些额外的步骤具体方法请看 [这个](https://github.com/wangyu-/udp2raw-tunnel/wiki/run-udp2raw-as-non-root) 链接。用非root运行更安全)
###### Server端输出:
![](/images/output_server.PNG)
###### Client端输出:
![](/images/output_client.PNG)
现在client和server之间建立起了tunnel。想要在本地连接44.55.66.77:7777只需要连接 127.0.0.1:3333。来回的所有的udp流量会被经过tunneling发送。在外界看起来是tcp流量不会有udp流量暴露到公网。
### MTU设置(重要)
不论你用udp2raw来加速kcptun还是vpn,为了稳定使用,都需要设置合理的MTU在kcptun/vpn里设置而不是在udp2raw里建议把MTU设置成1200。client和server端都要设置。
### 提醒
`--cipher-mode xor`表示仅使用简单的XOR加密这样可以节省CPU占用以免CPU成为速度瓶颈。如果你需要更强的加密可以去掉此选项使用默认的AES加密。加密相关的选项见后文的`--cipher-mode``--auth-mode`
如果要在anroid上运行请看[Android简明教程](/doc/android_guide.md)
`-a`选项会自动添加一条/几条iptables规则udp2raw必须和相应的iptables规则配合才能稳定工作一定要注意不要忘了`-a`(这是个常见错误)。 如果你不想让udp2raw自动添加iptables规则可以自己手动添加相应的iptables规则(看一下`-g`选项),然后以不带`-a`的方式运行udp2raw。
# 进阶操作说明
### 命令选项
```
udp2raw-tunnel
git version:6e1df4b39f build date:Oct 24 2017 09:21:15
repository: https://github.com/wangyu-/udp2raw-tunnel
usage:
run as client : ./this_program -c -l local_listen_ip:local_port -r server_address:server_port [options]
run as server : ./this_program -s -l server_listen_ip:server_port -r remote_address:remote_port [options]
common options,these options must be same on both side:
--raw-mode <string> available values:faketcp(default),udp,icmp
-k,--key <string> password to gen symetric key,default:"secret key"
--cipher-mode <string> available values:aes128cbc(default),xor,none
--auth-mode <string> available values:hmac_sha1,md5(default),crc32,simple,none
-a,--auto-rule auto add (and delete) iptables rule
-g,--gen-rule generate iptables rule then exit,so that you can copy and
add it manually.overrides -a
--disable-anti-replay disable anti-replay,not suggested
client options:
--source-ip <ip> force source-ip for raw socket
--source-port <port> force source-port for raw socket,tcp/udp only
this option disables port changing while re-connecting
other options:
--conf-file <string> read options from a configuration file instead of command line.
check example.conf in repo for format
--fifo <string> use a fifo(named pipe) for sending commands to the running program,
check readme.md in repository for supported commands.
--log-level <number> 0:never 1:fatal 2:error 3:warn
4:info (default) 5:debug 6:trace
--log-position enable file name,function name,line number in log
--disable-color disable log color
--disable-bpf disable the kernel space filter,most time its not necessary
unless you suspect there is a bug
--sock-buf <number> buf size for socket,>=10 and <=10240,unit:kbyte,default:1024
--force-sock-buf bypass system limitation while setting sock-buf
--seq-mode <number> seq increase mode for faketcp:
0:static header,do not increase seq and ack_seq
1:increase seq for every packet,simply ack last seq
2:increase seq randomly, about every 3 packets,simply ack last seq
3:simulate an almost real seq/ack procedure(default)
4:similiar to 3,but do not consider TCP Option Window_Scale,
maybe useful when firewall doesnt support TCP Option
--lower-level <string> send packets at OSI level 2, format:'if_name#dest_mac_adress'
ie:'eth0#00:23:45:67:89:b9'.or try '--lower-level auto' to obtain
the parameter automatically,specify it manually if 'auto' failed
--gen-add generate iptables rule and add it permanently,then exit.overrides -g
--keep-rule monitor iptables and auto re-add if necessary.implys -a
--clear clear any iptables rules added by this program.overrides everything
-h,--help print this help message
```
### iptables 规则,`-a``-g`
用raw收发tcp包本质上绕过了linux内核的tcp协议栈。linux碰到raw socket发来的包会不认识如果一直收到不认识的包会回复大量RST造成不稳定或性能问题。所以强烈建议添加iptables规则屏蔽Linux内核的对指定端口的处理。用-a选项udp2raw会在启动的时候自动帮你加上Iptables规则退出的时候再自动删掉。如果长期使用可以用-g选项来生成相应的Iptables规则再自己手动添加这样规则不会在udp2raw退出时被删掉可以避免停掉udp2raw后内核向对端回复RST。
用raw收发udp包也类似只是内核回复的是icmp unreachable。而用raw 收发icmp内核会自动回复icmp echo。都需要相应的iptables规则。
### `--cipher-mode``--auth-mode`
如果要最大的安全性建议用aes128cbc+hmac_sha1。如果要运行在路由器上建议用xor+simple可以节省CPU。但是注意xor+simple只能骗过防火墙的包检测不能防止真正的攻击者。
### `--seq-mode`
faketcp模式并没有模拟tcp的全部。所以理论上有办法把faketcp和真正的tcp流量区分开来虽然大部分ISP不太可能做这种程度的包检测。seq-mode可以改变一些seq ack的行为。如果遇到了连接问题可以尝试更改。在我这边的移动线路用3种模式都没问题。
### `--keep-rule`
定期主动检查iptables如果udp2raw添加的iptables规则丢了就重新添加。在一些iptables可能会被其他程序清空的情况下(比如梅林固件和openwrt的路由器)格外有用。
### `--fifo`
指定一个fifo(named pipe)来向运行中的程序发送命令,例如`--fifo fifo.file`
在client端,可以用`echo reconnect >fifo.file`来强制client换端口重连上层不断线.对Server目前没有效果。
### `--lower-level`
大部分udp2raw不能连通的情况都是设置了不兼容的iptables造成的。--lower-level选项允许绕过本地iptables。在一些iptables不好改动的情况下尤其有效比如你用的是梅林固件iptables全是固件自己生成的
##### 格式
`if_name#dest_mac_adress`,例如 `eth0#00:23:45:67:89:b9``eth0`换成你的出口网卡名。`00:23:45:67:89:b9`换成网关的mac地址如果client和server在同一个局域网内可能不需要网关这时候直接用对方主机的mac地址这个属于罕见的应用场景可以忽略
可以用`--lower-level auto`自动获取参数,如果获取参数失败,再手动填写。
##### client端获得--lower-level参数的办法
在client 端,运行`traceroute <server_ip>`,记下第一跳的地址,这个就是`网关ip`。再运行`arp -s <网关ip>`可以同时查到出口网卡名和mac。
![](/images/lower_level.PNG)
如果traceroute第一跳结果是`* * *`说明网关屏蔽了对traceroute的应答。需要用`ip route``route`查询网关:
![](/images/route.PNG)
##### server端获得--lower-level参数的办法
如果client有公网ip`traceroute <client_ip>`。下一步和client端的方法一样。
如果client没有公网ip`traceroute google.com``traceroute baidu.com`。下一步和client端的方法一样。
server端也可以用`--lower-level auto` 来尝试自动获得参数,如果无法连接再手动填写。
##### 注意
如果用了`--lower-level`选项。server虽然还可以bind在0.0.0.0,但是因为你显式指定了网络接口,就只能工作在这一个网络接口了。
如果`arps -s`命令查询不到首先再试几次。如果还是查询不到那么可能是因为你用的是pppoe方式的拨号宽带查询不到是正常的。这种情况下`if_name`填pppoe产生的虚拟interface通常名字叫`pppXXXX`,从`ifconfig`命令的输出里找一下;`des_mac_adress``00:00:00:00:00:00`,例如`ppp0#00:00:00:00:00:00`
### `--conf-file`
为了避免将密码等私密信息暴露给`ps`命令,你也可以使用 `配置文件` 来存储参数。
比如,将以上服务端参数改写成配置文件
`server.conf`:
```
-s
# 你可以像这样添加注释
# 注意,只有整行注释才能在配置文件里使用
# 注释必须独占一行
-l 0.0.0.0:4096
-r 127.0.0.1:7777
-a
-k passwd
--raw-mode faketcp
```
注意,当写入配置文件的时候,密码等参数两边的引号必须去除。
然后就可以使用下面的方式启动服务端
```bash
./udp2raw_amd64 --conf-file server.conf
```
# 性能测试
iperf3 的UDP模式有BUG所以这里用iperf3的tcp模式配合Openvpn测试udp2raw的性能。iperf3 udp issue ,https://github.com/esnet/iperf/issues/296
openvpn关掉了自带的加密。
#### iperf3 命令:
```
iperf3 -c 10.222.2.1 -P40
iperf3 -c 10.222.2.1 -P40 -R
```
#### client主机
vultr 2.5美元每月套餐(single core 2.4ghz cpu,512m ram,日本东京机房),
#### server主机
bandwagonhost 3.99美元每年套餐(single core 2.0ghz cpu,128m ram,美国洛杉矶机房)
### 测试1
raw_mode: faketcp cipher_mode: xor  auth_mode: simple
![image4](/images/image4.PNG)
(反向的速度几乎一样,所以只发正向测试的图)
测试中cpu被打满。其中有30%的cpu是被openvpn占的。 如果不用Openvpn中转实际达到100+Mb/S 应该没问题。
### 测试2
raw_mode: faketcp cipher_mode: aes128cbc  auth_mode: md5
![image5](/images/image5.PNG)
(反向的速度几乎一样,所以只发正向测试的图)
测试中cpu被打满。绝大多数cpu都是被udp2raw占用的主要消耗在aes加密。即使不用Openvpn速度也不会快很多了。
# 应用
### 中转 kcptun
[udp2raw+kcptun step_by_step教程](kcptun_step_by_step.md)
### 中转 finalspeed
[udp2raw+finalspeed step_by_step教程](finalspeed_step_by_step.md)
# wiki
更多内容请看 wiki:
https://github.com/wangyu-/udp2raw-tunnel/wiki

29
doc/android_guide.md Normal file
View File

@ -0,0 +1,29 @@
# How to run udp2raw on a rooted android device(arm cpu)
There is currently no GUI for udp2raw on android.Make sure you have installed Terminal to run it.Your device has to be rooted,otherwise you cant use raw socket.
Download udp2raw_arm from https://github.com/wangyu-/udp2raw-tunnel/releases.
Copy udp2raw_arm to any dir of your **internal storage** .Copying it to **SD card wont work**.
# Steps
1. run udp2raw_arm as usual, except you must change the -a option to -g
```
./udp2raw_arm -c -r 44.55.66.77:9966 -l 0.0.0.0:4000 -k1234 --cipher xor -g
```
2. find the generated iptables rule from udp2raw's output,add it manually by running:
```
iptables -I INPUT -s 44.55.66.77/32 -p tcp -m tcp --sport 9966 -j DROP
```
3. run udp2raw_ram without -g command
```
./udp2raw_arm -c -r 44.55.66.77:9966 -l 0.0.0.0:4000 -k1234 --cipher xor
```
# ScreenShot
zoom-in if not large enough
![](/images/android.png)

92
doc/build_guide.md Normal file
View File

@ -0,0 +1,92 @@
# udp2raw build guide
the guide on how to build udp2raw
## Build udp2raw for a specific platform
### linux platform which supports local compile
such as PC,raspberry pi
##### install git
run on debian/ubuntun
```
sudo apt-get install git
```
run on redhat/centos:
```
sudo yum install git
```
##### clone git code
run in any dir
```
git clone https://github.com/wangyu-/udp2raw-tunnel.git
cd udp2raw-tunnel
```
##### install compile tool
run on debian/ubuntun
```
sudo apt-get install build-essential
```
run on redhat/centos:
```
sudo yum groupinstall 'Development Tools'
```
run 'make'compilation done. the udp2raw file is the just compiled binary
### platform which needs cross-compile
such as openwrt router,run following instructions on your PC
##### install git
run on debian/ubuntun
```
sudo apt-get install git
```
run on redhat/centos:
```
sudo yum install git
```
##### download cross compile tool chain
find it on downloads.openwrt.org according to your openwrt version and cpu model.
for example, my tplink wdr4310 runs chaos_calmer 15.05,its with ar71xx cpudownload the following package.
```
http://downloads.openwrt.org/chaos_calmer/15.05/ar71xx/generic/OpenWrt-SDK-15.05-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64.tar.bz2
```
unzip it to any dir,such as /home/wangyu/OpenWrt-SDK-ar71xx-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2
cd into staging_dir toolchain-xxxxx bin .find the soft link with g++ suffix. in my case ,its mips-openwrt-linux-g++ ,check for its full path:
```
/home/wangyu/Desktop/OpenWrt-SDK-15.05-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-g++
```
##### compile
modify first line of makefile to:
```
cc_cross=/home/wangyu/Desktop/OpenWrt-SDK-15.05-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-g++
```
run `make cross`the just generated `udp2raw_cross` is the binary,compile done. copy it to your router to run.
`make cross` generates non-static binary. If you have any problem on running it,try to compile a static binary by using `make cross2` or `make cross3`.If your toolchain supports static compiling, usually one of them will succeed. The generated file is still named `udp2raw_cross`.
## Build a full release (include all binaries supported in the makefile)
1. make sure your linux is amd64 version
2. clone the repo
3. make sure you have g++ , make sure your g++ support the `-m32` option; make your your have installed libraries for `-m32` option
4. download https://github.com/wangyu-/files/releases/download/files/toolchains.tar.gz , and extract it to the right position (according to the makefile)
5. run `make release` inside udp2raw's directory

74
doc/build_guide.zh-cn.md Normal file
View File

@ -0,0 +1,74 @@
# udp2raw编译方法
本文演示怎么把udp2raw编译到自己所需的平台。
## 可以本地编译的linux平台
比如电脑、树莓派
##### 首先安装git
debian/ubuntun执行
```
sudo apt-get install git
```
redhat/centos执行:
```
sudo yum install git
```
##### 用git把源码clone至本地
在任意目录执行:
```
git clone https://github.com/wangyu-/udp2raw-tunnel.git
cd udp2raw-tunnel
```
##### 安装g++ make 等工具
debian/ubuntun执行
```
sudo apt-get install build-essential
```
redhat/centos执行:
```
sudo yum groupinstall 'Development Tools'
```
然后运行make编译完成。 生成的udp2raw就是编译好的bianry。
## 需要交叉编译的平台
比如各种openwrt路由器
##### 首先安装git
debian/ubuntun执行
```
sudo apt-get install git
```
redhat/centos执行:
```
sudo yum install git
```
##### 下载安装交叉编译工具包
去downloads.openwrt.org上找到自己的openwrt版本和cpu型号对应的SDK。通常openwrt版本号不一样也问题不大最主要是cpu型号。
比如我的tplink wdr4310运行的是chaos_calmer 15.05,ar71xx cpu应该下载这个包
```
http://downloads.openwrt.org/chaos_calmer/15.05/ar71xx/generic/OpenWrt-SDK-15.05-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64.tar.bz2
```
解压到本地任意目录,比如:/home/wangyu/OpenWrt-SDK-ar71xx-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2
让后依次进入staging_dir toolchain-xxxxx bin 目录找到后缀是g++的软链,比如我的是mips-openwrt-linux-g++ ,记下这个文件的完整路径:
```
/home/wangyu/Desktop/OpenWrt-SDK-15.05-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-g++
```
##### 编译
把makefile的第一行 cross_cc=后面的内容改成你刚才记下的完整路径:
```
cc_cross=/home/wangyu/Desktop/OpenWrt-SDK-15.05-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-g++
```
执行`make cross`目录下生成udp2raw_cross文件。编译完成。
`make cross`编译出的binary是非静态的。如果运行有问题可以尝试用`make cross2``make cross3`编译静态的binary,你的工具链必须带静态库才能成功编译,生成的文件仍然叫udp2raw_cross.

View File

@ -0,0 +1,71 @@
# udp2raw+finalspeed 加速tcp流量 Step by Step 教程
![image](finalspeed_step_by_step/Capture0.PNG)
##### 背景
国内有些ISP会对UDP做QOS或屏蔽这时候加速协议对TCP发包模式的支持就很重要。finalspeed虽然本身支持在底层用TCP发包但是其依赖的libpcap不支持openvz架构即使不是openvz架构的主机也存在不稳定的问题。
##### 摘要
udp2raw是一个把udp流量通过raw socket包装成tcp流量的工具。通过用udp2raw配合udp模式的 finalspeed一样可以达到在底层发tcp包绕过QOS的效果。支持openvz,稳定性也好很多。原理上相当于在finalspeed外面再包了一层tunnel。
本教程会一步一步演示用udp2raw+finalspeed加速http流量的过程。加速任何其他tcp流量也一样包括$\*\*\*。本文避免讨论科学上网所以只演示加速http流量。
udp2raw也支持把udp流量包装成Icmp发送本教程不做演示。
### 环境要求
服务器主机是linux有root权限。  可以是openvz架构的vps。 也可以是openwrt路由器。
本地主机是windows,本地有openwrt路由器或树莓派或安装了linux虚拟机网卡设置为桥接模式
(如果嫌给虚拟机安装linux麻烦可以用release里发布的预装了udp2raw的openwrt_x86虚拟机镜像容量4.4mb)
下面的教程按虚拟机演示如果你有openwrt路由器或树莓派可以直接运行再路由器或树莓派上就不需要虚拟机了。
### 安装
下载好udp2raw的压缩包解压分别解压到服务器和本地的虚拟机。
https://github.com/wangyu-/udp2raw-tunnel/releases
在服务器端安装好finalspeed服务端在本地windows安装好finalspeed的客户端。服务端我以前是用91yun的一键安装脚本安装的没装过的可以去网上搜一键安装脚本。
### 运行
1.先在服务器主机运行如下命令确定finalspeed服务端已经正常启动了。
```
netstat -nlp|grep java
```
![image](finalspeed_step_by_step/Capture5.PNG)
如果显示了150端口就表示服务端启动好了。
2.在服务器启动udp2raw server
```
./udp2raw_amd64 -s -l0.0.0.0:8855 -r 127.0.0.1:150 -a -k "passwd" --raw-mode faketcp
```
![image](finalspeed_step_by_step/Capture2.PNG)
3.在本地的虚拟机上启动udp2raw client ,假设服务器ip是45.66.77.88
```
./udp2raw_amd64 -c -r45.66.77.88:8855 -l0.0.0.0:150 --raw-mode faketcp -a -k"passwd"
```
如果一切正常client端会显示client_ready:
![image](finalspeed_step_by_step/Capture3.PNG)
记下红框中的ip,这是虚拟机的网卡ip
在server端也会显示server_ready
![image](finalspeed_step_by_step/Capture4.PNG)
4.在本地windows,按图配置好finalspeed的客户端。注意192.168.205.8改成你刚才记下来的IP带宽也要按实际的填。传输协议要选UDP.
![image](finalspeed_step_by_step/Capture.PNG)
5.所有准备工作已经完成了在本地访问本地的8012端口相当于访问服务器的80端口。
来试一下通过http://127.0.0.1:8012/ 下载文件 1.5M/s
![image](finalspeed_step_by_step/Capture6.PNG)
再试一下直接通过服务器的ip访问http://45.66.77.88:80/ 速度只有600K/s
![image](finalspeed_step_by_step/Capture7.PNG)
教程就到这里了用来加速其他的tcp服务也是一样的只要再第三步那里设置其他的端口。

View File

@ -0,0 +1 @@
11

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

View File

@ -0,0 +1,63 @@
# udp2raw+kcptun 加速tcp流量 Step by Step 教程
![image](kcptun_step_by_step/Capture00.PNG)
本教程会一步一步演示用udp2raw+kcptun加速SSH流量的过程。加速任何其他tcp流量也一样包括$\*\*\*本文避免涉及科学上网所以演示ssh。
### 环境要求
两边的主机都是linux有root权限。 可以是openwrt路由器或树莓派也可以是root了的android。
在windows/mac上运行udp2raw可以参考这个教程
https://github.com/wangyu-/udp2raw-tunnel/wiki/在windows-mac上运行udp2raw客户端带图形界面
### 安装
下载好kcptun和udp2raw的压缩包解压分别解压到client端和server端。
https://github.com/xtaci/kcptun/releases
https://github.com/wangyu-/udp2raw-tunnel/releases
解压好后,如图:
![image](kcptun_step_by_step/Capture0.PNG)
### 运行
1.在远程服务器运行 udp2raw_amd64 server模式
```
./udp2raw_amd64 -s -l0.0.0.0:8855 -r 127.0.0.1:4000 -k "passwd" --raw-mode faketcp -a
```
![image](kcptun_step_by_step/Capture.PNG)
2.在本地运行udp2raw_amd64 client模式假设server ip是45.66.77.88
```
./udp2raw_amd64 -c -r45.66.77.88:8855 -l0.0.0.0:4000 --raw-mode faketcp -a -k"passwd"
```
如果一切正常client端输出如下显示client_ready
![image](kcptun_step_by_step/Capture2.PNG)
server端也会有类似输出,显示server_ready
![image](kcptun_step_by_step/Capture3.PNG)
3.在远程服务器运行 kcp server
```
./server_linux_amd64 -t "127.0.0.1:22" -l ":4000" -mode fast2 -mtu 1300
```
-mtu 1300很重要或者设置成更小。
![image](kcptun_step_by_step/Capture6.PNG)
4.在本地运行
```
./client_linux_amd64 -r "127.0.0.1:4000" -l ":3322" -mode fast2 -mtu 1300
```
-mtu 1300很重要或者设置成更小。
![image](kcptun_step_by_step/Capture7.PNG)
5.所有准备工作已经做好,在本地运行
```
ssh -p 3322 root@127.0.0.1
```
已经连进去了而且是经过kcptun加速的
![image](kcptun_step_by_step/Capture8.PNG)

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

94
doc/openvpn_guide.md Normal file
View File

@ -0,0 +1,94 @@
# udp2raw+openvpn config guide
![image_vpn](/images/openvpn.PNG)
![image4](/images/image4.PNG)
# udp2raw command
#### run at server side
```
./udp2raw_amd64 -s -l0.0.0.0:8855 -r 127.0.0.1:7777 -k "passwd" --raw-mode faketcp -a
```
#### run at client side
assume server ip is 45.66.77.88
```
./udp2raw_amd64 -c -l0.0.0.0:3333 -r 45.66.77.88:8855 -k "passwd" --raw-mode faketcp -a
```
#### hint
You can add `--cipher-mode xor` `--auth-mode simple` to **both** sides to obtain maximum performance(but poor security).
# openvpn config
#### client side config
```
client
dev tun100
proto udp
remote 127.0.0.1 3333
resolv-retry infinite
nobind
persist-key
persist-tun
ca /root/add-on/openvpn/ca.crt
cert /root/add-on/openvpn/client.crt
key /root/add-on/openvpn/client.key
keepalive 3 20
verb 3
mute 20
comp-lzo no
cipher none ##### disable openvpn 's cipher and auth for maxmized peformance.
auth none ##### you can enable openvpn's cipher and auth,if you dont care about peformance,or you dont trust udp2raw 's encryption
fragment 1200 ##### very important you can turn it up a bit. but,the lower the safer
mssfix 1200 ##### very important
sndbuf 2000000 ##### important
rcvbuf 2000000 ##### important
txqueuelen 4000 ##### suggested
```
#### server side config
```
local 0.0.0.0
port 7777
proto udp
dev tun
ca /etc/openvpn/easy-rsa/2.0/keys/ca.crt
cert /etc/openvpn/easy-rsa/2.0/keys/server.crt
key /etc/openvpn/easy-rsa/2.0/keys/server.key
dh /etc/openvpn/easy-rsa/2.0/keys/dh1024.pem
server 10.222.2.0 255.255.255.0
ifconfig 10.222.2.1 10.222.2.6
client-to-client
duplicate-cn
keepalive 10 60
max-clients 50
persist-key
persist-tun
status /etc/openvpn/openvpn-status.log
verb 3
mute 20
comp-lzo no
cipher none ##### disable openvpn 's cipher and auth for maxmized peformance.
auth none ##### you can enable openvpn's cipher and auth,if you dont care about peformance,or you dont trust udp2raw 's encryption
fragment 1200 ##### very important you can turn it up a bit. but,the lower the safer
mssfix 1200 ##### very important
sndbuf 2000000 ##### important
rcvbuf 2000000 ##### important
txqueuelen 4000 ##### suggested
```

733
encrypt.cpp Executable file → Normal file
View File

@ -1,44 +1,133 @@
#include <lib/aes.h>
#include <lib/md5.h>
#include "lib/aes-common.h"
#include "lib/md5.h"
#include "lib/pbkdf2-sha1.h"
#include "lib/pbkdf2-sha256.h"
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <encrypt.h>
#include <common.h>
#include "encrypt.h"
#include "common.h"
#include "log.h"
//static uint64_t seq=1;
// static uint64_t seq=1;
static int8_t zero_iv[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0};//this prog use zero iv,you should make sure first block of data contains a random/nonce data
static int8_t zero_iv[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // this prog use zero iv,you should make sure first block of data contains a random/nonce data
/****
* security of zero_iv + nonce first data block
* https://crypto.stackexchange.com/questions/5421/using-cbc-with-a-fixed-iv-and-a-random-first-plaintext-block
****/
char normal_key[16 + 100]; // generated from key_string by md5. reserved for compatiblity
const int hmac_key_len = 64; // generate 512bit long keys, use first n chars when needed
const int cipher_key_len = 64;
unsigned char hmac_key_encrypt[hmac_key_len + 100]; // key for hmac
unsigned char hmac_key_decrypt[hmac_key_len + 100]; // key for hmac
unsigned char cipher_key_encrypt[cipher_key_len + 100]; // key for aes etc.
unsigned char cipher_key_decrypt[cipher_key_len + 100]; // key for aes etc.
unordered_map<int, const char *> auth_mode_tostring = {{auth_none, "none"}, {auth_md5, "md5"}, {auth_crc32, "crc32"},{auth_simple,"simple"}};
unordered_map<int, const char *> cipher_mode_tostring={{cipher_none,"none"},{cipher_aes128cbc,"aes128cbc"},{cipher_xor,"xor"}};
char gro_xor[256 + 100]; // dirty fix for gro
auth_mode_t auth_mode=auth_crc32;
cipher_mode_t cipher_mode=cipher_aes128cbc;
unordered_map<int, const char *> auth_mode_tostring = {
{auth_none, "none"},
{auth_md5, "md5"},
{auth_crc32, "crc32"},
{auth_simple, "simple"},
{auth_hmac_sha1, "hmac_sha1"},
};
unordered_map<int, const char *> cipher_mode_tostring = {
{cipher_none, "none"},
{cipher_aes128cfb, "aes128cfb"},
{cipher_aes128cbc, "aes128cbc"},
{cipher_xor, "xor"},
};
// TODO aes-gcm
auth_mode_t auth_mode = auth_md5;
cipher_mode_t cipher_mode = cipher_aes128cbc;
int is_hmac_used = 0;
int aes128cfb_old = 0;
// TODO key negotiation and forward secrecy
int my_init_keys(const char *user_passwd, int is_client) {
char tmp[1000] = "";
int len = strlen(user_passwd);
strcat(tmp, user_passwd);
strcat(tmp, "key1");
md5((uint8_t *)tmp, strlen(tmp), (uint8_t *)normal_key);
if (auth_mode == auth_hmac_sha1)
is_hmac_used = 1;
if (is_hmac_used || g_fix_gro || 1) {
unsigned char salt[400] = "";
char salt_text[400] = "udp2raw_salt1";
md5((uint8_t *)(salt_text), strlen(salt_text), salt); // TODO different salt per session
unsigned char pbkdf2_output1[400] = "";
PKCS5_PBKDF2_HMAC_SHA256((uint8_t *)user_passwd, len, salt, 16, 10000, 32, pbkdf2_output1); // TODO argon2 ?
// unsigned char pbkdf2_output2[400]="";
// PKCS5_PBKDF2_HMAC_SHA256(pbkdf2_output1,32,0,0,1, hmac_key_len*2+cipher_key_len*2,pbkdf2_output2); //stretch it
const char *info_hmac_encrypt = "hmac_key server-->client";
const char *info_hmac_decrypt = "hmac_key client-->server";
const char *info_cipher_encrypt = "cipher_key server-->client";
const char *info_cipher_decrypt = "cipher_key client-->server";
if (is_client) {
const char *tmp;
tmp = info_hmac_encrypt;
info_hmac_encrypt = info_hmac_decrypt;
info_hmac_decrypt = tmp;
tmp = info_cipher_encrypt;
info_cipher_encrypt = info_cipher_decrypt;
info_cipher_decrypt = tmp;
} else {
// nop
}
assert(hkdf_sha256_expand(pbkdf2_output1, 32, (unsigned char *)info_cipher_encrypt, strlen(info_cipher_encrypt), cipher_key_encrypt, cipher_key_len) == 0);
assert(hkdf_sha256_expand(pbkdf2_output1, 32, (unsigned char *)info_cipher_decrypt, strlen(info_cipher_decrypt), cipher_key_decrypt, cipher_key_len) == 0);
assert(hkdf_sha256_expand(pbkdf2_output1, 32, (unsigned char *)info_hmac_encrypt, strlen(info_hmac_encrypt), hmac_key_encrypt, hmac_key_len) == 0);
assert(hkdf_sha256_expand(pbkdf2_output1, 32, (unsigned char *)info_hmac_decrypt, strlen(info_hmac_decrypt), hmac_key_decrypt, hmac_key_len) == 0);
const char *gro_info = "gro";
assert(hkdf_sha256_expand(pbkdf2_output1, 32, (unsigned char *)gro_info, strlen(gro_info), (unsigned char *)gro_xor, 256) == 0);
}
print_binary_chars(normal_key, 16);
print_binary_chars((char *)hmac_key_encrypt, hmac_key_len);
print_binary_chars((char *)hmac_key_decrypt, hmac_key_len);
print_binary_chars((char *)cipher_key_encrypt, cipher_key_len);
print_binary_chars((char *)cipher_key_decrypt, cipher_key_len);
return 0;
}
/*
* this function comes from http://www.hackersdelight.org/hdcodetxt/crc.c.txt
*/
unsigned int crc32h(unsigned char *message,int len) {
unsigned int crc32h(unsigned char *message, int len) {
int i, crc;
unsigned int byte, c;
const unsigned int g0 = 0xEDB88320, g1 = g0>>1,
g2 = g0>>2, g3 = g0>>3, g4 = g0>>4, g5 = g0>>5,
g6 = (g0>>6)^g0, g7 = ((g0>>6)^g0)>>1;
const unsigned int g0 = 0xEDB88320, g1 = g0 >> 1,
g2 = g0 >> 2, g3 = g0 >> 3, g4 = g0 >> 4, g5 = g0 >> 5,
g6 = (g0 >> 6) ^ g0, g7 = ((g0 >> 6) ^ g0) >> 1;
i = 0;
crc = 0xFFFFFFFF;
while (i!=len) { // Get next byte.
while (i != len) { // Get next byte.
byte = message[i];
crc = crc ^ byte;
c = ((crc<<31>>31) & g7) ^ ((crc<<30>>31) & g6) ^
((crc<<29>>31) & g5) ^ ((crc<<28>>31) & g4) ^
((crc<<27>>31) & g3) ^ ((crc<<26>>31) & g2) ^
((crc<<25>>31) & g1) ^ ((crc<<24>>31) & g0);
c = ((crc << 31 >> 31) & g7) ^ ((crc << 30 >> 31) & g6) ^
((crc << 29 >> 31) & g5) ^ ((crc << 28 >> 31) & g4) ^
((crc << 27 >> 31) & g3) ^ ((crc << 26 >> 31) & g2) ^
((crc << 25 >> 31) & g1) ^ ((crc << 24 >> 31) & g0);
crc = ((unsigned)crc >> 8) ^ c;
i = i + 1;
}
@ -57,373 +146,443 @@ unsigned int crc32h(unsigned char *message,int len) {
return ;
}*/
void simple_hash(unsigned char *str,int len,unsigned char res[8]) //djb2+ sdbm
void simple_hash(unsigned char *str, int len, unsigned char res[8]) // djb2+ sdbm
{
u32_t hash = 5381;
u32_t hash2 = 0;
int c;
int i=0;
while(c = *str++,i++!=len)
{
int i = 0;
while (c = *str++, i++ != len) {
// hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
hash = ((hash << 5) + hash)^c; /* (hash * 33) ^ c */
hash = ((hash << 5) + hash) ^ c; /* (hash * 33) ^ c */
hash2 = c + (hash2 << 6) + (hash2 << 16) - hash2;
}
hash=htonl(hash);
hash2=htonl(hash2);
memcpy(res,&hash,sizeof(hash));
memcpy(res+sizeof(hash),&hash2,sizeof(hash2));
hash = htonl(hash);
hash2 = htonl(hash2);
memcpy(res, &hash, sizeof(hash));
memcpy(res + sizeof(hash), &hash2, sizeof(hash2));
}
int auth_md5_cal(const char *data, char *output, int &len) {
memcpy(output, data, len); // TODO inefficient code
md5((unsigned char *)output, len, (unsigned char *)(output + len));
len += 16;
return 0;
}
int auth_hmac_sha1_cal(const char *data, char *output, int &len) {
mylog(log_trace, "auth_hmac_sha1_cal() is called\n");
memcpy(output, data, len); // TODO inefficient code
sha1_hmac(hmac_key_encrypt, 20, (const unsigned char *)data, len, (unsigned char *)(output + len));
// use key len of 20 instead of hmac_key_len, "extra length would not significantly increase the function strength" (rfc2104)
len += 20;
return 0;
}
int auth_hmac_sha1_verify(const char *data, int &len) {
mylog(log_trace, "auth_hmac_sha1_verify() is called\n");
if (len < 20) {
mylog(log_trace, "auth_hmac_sha1_verify len<20\n");
return -1;
}
char res[20];
int auth_md5_cal(const char *data,char * output,int &len)
{
memcpy(output,data,len);//TODO inefficient code
md5((unsigned char *)output,len,(unsigned char *)(output+len));
len+=16;
sha1_hmac(hmac_key_decrypt, 20, (const unsigned char *)data, len - 20, (unsigned char *)(res));
if (memcmp(res, data + len - 20, 20) != 0) {
mylog(log_trace, "auth_hmac_sha1 check failed\n");
return -2;
}
len -= 20;
return 0;
}
int auth_crc32_cal(const char *data,char * output,int &len)
{
memcpy(output,data,len);//TODO inefficient code
unsigned int ret=crc32h((unsigned char *)output,len);
unsigned int ret_n=htonl(ret);
memcpy(output+len,&ret_n,sizeof(unsigned int));
len+=sizeof(unsigned int);
int auth_crc32_cal(const char *data, char *output, int &len) {
memcpy(output, data, len); // TODO inefficient code
unsigned int ret = crc32h((unsigned char *)output, len);
unsigned int ret_n = htonl(ret);
memcpy(output + len, &ret_n, sizeof(unsigned int));
len += sizeof(unsigned int);
return 0;
}
int auth_simple_cal(const char *data,char * output,int &len)
{
//char res[4];
memcpy(output,data,len);//TODO inefficient code
simple_hash((unsigned char *)output,len,(unsigned char *)(output+len));
len+=8;
int auth_simple_cal(const char *data, char *output, int &len) {
// char res[4];
memcpy(output, data, len); // TODO inefficient code
simple_hash((unsigned char *)output, len, (unsigned char *)(output + len));
len += 8;
return 0;
}
int auth_simple_verify(const char *data,int &len)
{
if(len<8) return -1;
int auth_simple_verify(const char *data, int &len) {
if (len < 8) return -1;
unsigned char res[8];
len-=8;
simple_hash((unsigned char *)data,len,res);
if(memcmp(res,data+len,8)!=0)
len -= 8;
simple_hash((unsigned char *)data, len, res);
if (memcmp(res, data + len, 8) != 0)
return -1;
return 0;
}
int auth_none_cal(const char *data,char * output,int &len)
{
memcpy(output,data,len);
int auth_none_cal(const char *data, char *output, int &len) {
memcpy(output, data, len);
return 0;
}
int auth_md5_verify(const char *data,int &len)
{
if(len<16)
{
mylog(log_trace,"auth_md5_verify len<16\n");
int auth_md5_verify(const char *data, int &len) {
if (len < 16) {
mylog(log_trace, "auth_md5_verify len<16\n");
return -1;
}
char md5_res[16];
md5((unsigned char *)data,len-16,(unsigned char *)md5_res);
md5((unsigned char *)data, len - 16, (unsigned char *)md5_res);
if(memcmp(md5_res,data+len-16,16)!=0)
{
mylog(log_trace,"auth_md5_verify md5 check failed\n");
if (memcmp(md5_res, data + len - 16, 16) != 0) {
mylog(log_trace, "auth_md5_verify md5 check failed\n");
return -2;
}
len-=16;
len -= 16;
return 0;
}
int auth_none_verify(const char *data,int &len)
{
int auth_none_verify(const char *data, int &len) {
return 0;
}
int cipher_xor_encrypt(const char * data, char *output,int &len, char *key) {
int cipher_xor_encrypt(const char *data, char *output, int &len, char *key) {
int i, j;
for (i = 0, j = 0; i < len; i++, j++) {
if(j==16) j=0;
output[i] = data[i]^key[j];
if (j == 16) j = 0;
output[i] = data[i] ^ key[j];
}
return 0;
}
int cipher_xor_decrypt(const char * data, char *output,int &len, char *key) {
int cipher_xor_decrypt(const char *data, char *output, int &len, char *key) {
int i, j;
//char tmp[buf_len];
//len=len/16*16+1;
//AES128_CBC_decrypt_buffer((uint8_t *)tmp, (uint8_t *)input, len, (uint8_t *)key, (uint8_t *)iv);
//for(i=0;i<len;i++)
//input[i]=tmp[i];
// char tmp[buf_len];
// len=len/16*16+1;
// AES128_CBC_decrypt_buffer((uint8_t *)tmp, (uint8_t *)input, len, (uint8_t *)key, (uint8_t *)iv);
// for(i=0;i<len;i++)
// input[i]=tmp[i];
for (i = 0, j = 0; i < len; i++, j++) {
if(j==16) j=0;
output[i] = data[i]^key[j];
if (j == 16) j = 0;
output[i] = data[i] ^ key[j];
}
return 0;
}
int padding(char *data ,int &data_len,int padding_num)
{
int old_len=data_len;
data_len+=1;
if(data_len%padding_num!=0)
{
data_len= (data_len/padding_num)*padding_num+padding_num;
int padding(char *data, int &data_len, int padding_num) {
int old_len = data_len;
data_len += 1;
if (data_len % padding_num != 0) {
data_len = (data_len / padding_num) * padding_num + padding_num;
}
data[data_len-1]= (data_len-old_len);
unsigned char *p = (unsigned char *)&data[data_len - 1];
*p = (data_len - old_len);
return 0;
}
int de_padding(const char *data ,int &data_len,int padding_num)
{
if((uint8_t)data[data_len-1] >padding_num) return -1;
data_len-=(uint8_t)data[data_len-1];
if(data_len<0)
{
int de_padding(const char *data, int &data_len, int padding_num) {
if (data_len == 0) return -1;
if ((uint8_t)data[data_len - 1] > padding_num) return -1;
data_len -= (uint8_t)data[data_len - 1];
if (data_len < 0) {
return -1;
}
return 0;
}
int cipher_aes128cbc_encrypt(const char *data,char *output,int &len,char * key)
{
void aes_ecb_encrypt(const char *data, char *output) {
static int first_time = 1;
char *key = (char *)cipher_key_encrypt;
if (aes_key_optimize) {
if (first_time == 0)
key = 0;
else
first_time = 0;
}
AES_ECB_encrypt_buffer((uint8_t *)data, (uint8_t *)key, (uint8_t *)output);
}
void aes_ecb_encrypt1(char *data) {
char buf[16];
memcpy(buf, data, 16);
aes_ecb_encrypt(buf, data);
}
void aes_ecb_decrypt(const char *data, char *output) {
static int first_time = 1;
char *key = (char *)cipher_key_decrypt;
if (aes_key_optimize) {
if (first_time == 0)
key = 0;
else
first_time = 0;
}
AES_ECB_decrypt_buffer((uint8_t *)data, (uint8_t *)key, (uint8_t *)output);
}
void aes_ecb_decrypt1(char *data) {
char buf[16];
memcpy(buf, data, 16);
aes_ecb_decrypt(buf, data);
}
int cipher_aes128cbc_encrypt(const char *data, char *output, int &len, char *key) {
static int first_time = 1;
char buf[buf_len];
memcpy(buf,data,len);//TODO inefficient code
memcpy(buf, data, len); // TODO inefficient code
if (padding(buf, len, 16) < 0) return -1;
/*
int ori_len=len;
len+=2;//length
if(len%16!=0)
{
len= (len/16)*16+16;
if (aes_key_optimize) {
if (first_time == 0)
key = 0;
else
first_time = 0;
}
//if(len>max_data_len) return -1;
buf[len-2]= (unsigned char)( (uint16_t(ori_len))>>8);
buf[len-1]=(unsigned char)( ((uint16_t(ori_len))<<8)>>8) ;*/
if(padding(buf,len,16)<0) return -1;
AES_CBC_encrypt_buffer((unsigned char *)output,(unsigned char *)buf,len,(unsigned char *)key,(unsigned char *)zero_iv);
AES_CBC_encrypt_buffer((unsigned char *)output, (unsigned char *)buf, len, (unsigned char *)key, (unsigned char *)zero_iv);
return 0;
}
int auth_crc32_verify(const char *data,int &len)
{
if(len<int(sizeof(unsigned int)))
{
mylog(log_debug,"auth_crc32_verify len<16\n");
int cipher_aes128cfb_encrypt(const char *data, char *output, int &len, char *key) {
static int first_time = 1;
assert(len >= 16);
char buf[buf_len];
memcpy(buf, data, len); // TODO inefficient code
if (aes_key_optimize) {
if (first_time == 0)
key = 0;
else
first_time = 0;
}
if (!aes128cfb_old) {
aes_ecb_encrypt(data, buf); // encrypt the first block
}
AES_CFB_encrypt_buffer((unsigned char *)output, (unsigned char *)buf, len, (unsigned char *)key, (unsigned char *)zero_iv);
return 0;
}
int auth_crc32_verify(const char *data, int &len) {
if (len < int(sizeof(unsigned int))) {
mylog(log_debug, "auth_crc32_verify len<%d\n", int(sizeof(unsigned int)));
return -1;
}
unsigned int ret=crc32h((unsigned char *)data,len-sizeof(unsigned int));
unsigned int ret_n=htonl(ret);
unsigned int ret = crc32h((unsigned char *)data, len - sizeof(unsigned int));
unsigned int ret_n = htonl(ret);
if(memcmp(data+len-sizeof(unsigned int),&ret_n,sizeof(unsigned int))!=0)
{
mylog(log_debug,"auth_crc32_verify memcmp fail\n");
if (memcmp(data + len - sizeof(unsigned int), &ret_n, sizeof(unsigned int)) != 0) {
mylog(log_debug, "auth_crc32_verify memcmp fail\n");
return -1;
}
len-=sizeof(unsigned int);
len -= sizeof(unsigned int);
return 0;
}
int cipher_none_encrypt(const char *data,char *output,int &len,char * key)
{
memcpy(output,data,len);
int cipher_none_encrypt(const char *data, char *output, int &len, char *key) {
memcpy(output, data, len);
return 0;
}
int cipher_aes128cbc_decrypt(const char *data,char *output,int &len,char * key)
{
int cipher_aes128cbc_decrypt(const char *data, char *output, int &len, char *key) {
static int first_time = 1;
if (len % 16 != 0) {
mylog(log_debug, "len%%16!=0\n");
return -1;
}
if (aes_key_optimize) {
if (first_time == 0)
key = 0;
else
first_time = 0;
}
AES_CBC_decrypt_buffer((unsigned char *)output, (unsigned char *)data, len, (unsigned char *)key, (unsigned char *)zero_iv);
if (de_padding(output, len, 16) < 0) return -1;
return 0;
}
int cipher_aes128cfb_decrypt(const char *data, char *output, int &len, char *key) {
static int first_time = 1;
if (len < 16) return -1;
if(len%16 !=0) {mylog(log_debug,"len%%16!=0\n");return -1;}
//if(len<0) {mylog(log_debug,"len <0\n");return -1;}
AES_CBC_decrypt_buffer((unsigned char *)output,(unsigned char *)data,len,(unsigned char *)key,(unsigned char *)zero_iv);
if(de_padding(output,len,16)<0) return -1;
if (aes_key_optimize) {
if (first_time == 0)
key = 0;
else
first_time = 0;
}
AES_CFB_decrypt_buffer((unsigned char *)output, (unsigned char *)data, len, (unsigned char *)key, (unsigned char *)zero_iv);
if (!aes128cfb_old)
aes_ecb_decrypt1(output); // decrypt the first block
// if(de_padding(output,len,16)<0) return -1;
return 0;
}
int cipher_none_decrypt(const char *data,char *output,int &len,char * key)
{
memcpy(output,data,len);
int cipher_none_decrypt(const char *data, char *output, int &len, char *key) {
memcpy(output, data, len);
return 0;
}
int auth_cal(const char *data,char * output,int &len)
{
mylog(log_trace,"auth:%d\n",auth_mode);
switch(auth_mode)
{
case auth_crc32:return auth_crc32_cal(data, output, len);
case auth_md5:return auth_md5_cal(data, output, len);
case auth_simple:return auth_simple_cal(data, output, len);
case auth_none:return auth_none_cal(data, output, len);
default: return auth_md5_cal(data,output,len);//default
int auth_cal(const char *data, char *output, int &len) {
mylog(log_trace, "auth:%d\n", auth_mode);
switch (auth_mode) {
case auth_crc32:
return auth_crc32_cal(data, output, len);
case auth_md5:
return auth_md5_cal(data, output, len);
case auth_simple:
return auth_simple_cal(data, output, len);
case auth_none:
return auth_none_cal(data, output, len);
case auth_hmac_sha1:
return auth_hmac_sha1_cal(data, output, len);
// default: return auth_md5_cal(data,output,len);//default;
default:
assert(0 == 1);
}
return -1;
}
int auth_verify(const char *data,int &len)
{
mylog(log_trace,"auth:%d\n",auth_mode);
switch(auth_mode)
{
case auth_crc32:return auth_crc32_verify(data, len);
case auth_md5:return auth_md5_verify(data, len);
case auth_simple:return auth_simple_verify(data, len);
case auth_none:return auth_none_verify(data, len);
default: return auth_md5_verify(data,len);//default
int auth_verify(const char *data, int &len) {
mylog(log_trace, "auth:%d\n", auth_mode);
switch (auth_mode) {
case auth_crc32:
return auth_crc32_verify(data, len);
case auth_md5:
return auth_md5_verify(data, len);
case auth_simple:
return auth_simple_verify(data, len);
case auth_none:
return auth_none_verify(data, len);
case auth_hmac_sha1:
return auth_hmac_sha1_verify(data, len);
// default: return auth_md5_verify(data,len);//default
default:
assert(0 == 1);
}
return -1;
}
int cipher_encrypt(const char *data,char *output,int &len,char * key)
{
mylog(log_trace,"cipher:%d\n",cipher_mode);
switch(cipher_mode)
{
case cipher_aes128cbc:return cipher_aes128cbc_encrypt(data,output,len, key);
case cipher_xor:return cipher_xor_encrypt(data,output,len, key);
case cipher_none:return cipher_none_encrypt(data,output,len, key);
default:return cipher_aes128cbc_encrypt(data,output,len, key);
int cipher_encrypt(const char *data, char *output, int &len, char *key) {
mylog(log_trace, "cipher:%d\n", cipher_mode);
switch (cipher_mode) {
case cipher_aes128cbc:
return cipher_aes128cbc_encrypt(data, output, len, key);
case cipher_aes128cfb:
return cipher_aes128cfb_encrypt(data, output, len, key);
case cipher_xor:
return cipher_xor_encrypt(data, output, len, key);
case cipher_none:
return cipher_none_encrypt(data, output, len, key);
// default:return cipher_aes128cbc_encrypt(data,output,len, key);
default:
assert(0 == 1);
}
return -1;
}
int cipher_decrypt(const char *data,char *output,int &len,char * key)
{
mylog(log_trace,"cipher:%d\n",cipher_mode);
switch(cipher_mode)
{
case cipher_aes128cbc:return cipher_aes128cbc_decrypt(data,output,len, key);
case cipher_xor:return cipher_xor_decrypt(data,output,len, key);
case cipher_none:return cipher_none_decrypt(data,output,len, key);
default: return cipher_aes128cbc_decrypt(data,output,len,key);
int cipher_decrypt(const char *data, char *output, int &len, char *key) {
mylog(log_trace, "cipher:%d\n", cipher_mode);
switch (cipher_mode) {
case cipher_aes128cbc:
return cipher_aes128cbc_decrypt(data, output, len, key);
case cipher_aes128cfb:
return cipher_aes128cfb_decrypt(data, output, len, key);
case cipher_xor:
return cipher_xor_decrypt(data, output, len, key);
case cipher_none:
return cipher_none_decrypt(data, output, len, key);
// default: return cipher_aes128cbc_decrypt(data,output,len,key);
default:
assert(0 == 1);
}
return -1;
}
int encrypt_AE(const char *data, char *output, int &len /*,char * key*/) {
mylog(log_trace, "encrypt_AE is called\n");
char buf[buf_len];
char buf2[buf_len];
memcpy(buf, data, len);
if (cipher_encrypt(buf, buf2, len, (char *)cipher_key_encrypt) != 0) {
mylog(log_debug, "cipher_encrypt failed ");
return -1;
}
if (auth_cal(buf2, output, len) != 0) {
mylog(log_debug, "auth_cal failed ");
return -1;
}
int my_encrypt(const char *data,char *output,int &len,char * key)
{
if(len<0) {mylog(log_trace,"len<0");return -1;}
if(len>max_data_len) {mylog(log_warn,"len>max_data_len");return -1;}
// printf("%d %x %x\n",len,(int)(output[0]),(int)(output[1]));
// print_binary_chars(output,len);
// use encrypt-then-MAC scheme
return 0;
}
int decrypt_AE(const char *data, char *output, int &len /*,char * key*/) {
mylog(log_trace, "decrypt_AE is called\n");
// printf("%d %x %x\n",len,(int)(data[0]),(int)(data[1]));
// print_binary_chars(data,len);
if (auth_verify(data, len) != 0) {
mylog(log_debug, "auth_verify failed\n");
return -1;
}
if (cipher_decrypt(data, output, len, (char *)cipher_key_decrypt) != 0) {
mylog(log_debug, "cipher_decrypt failed \n");
return -1;
}
return 0;
}
int my_encrypt(const char *data, char *output, int &len /*,char * key*/) {
if (len < 0) {
mylog(log_trace, "len<0");
return -1;
}
if (len > max_data_len) {
mylog(log_warn, "len>max_data_len");
return -1;
}
if (is_hmac_used)
return encrypt_AE(data, output, len);
char buf[buf_len];
char buf2[buf_len];
memcpy(buf,data,len);
if(auth_cal(buf,buf2,len)!=0) {mylog(log_debug,"auth_cal failed ");return -1;}
if(cipher_encrypt(buf2,output,len,key) !=0) {mylog(log_debug,"cipher_encrypt failed ");return -1;}
memcpy(buf, data, len);
if (auth_cal(buf, buf2, len) != 0) {
mylog(log_debug, "auth_cal failed ");
return -1;
}
if (cipher_encrypt(buf2, output, len, normal_key) != 0) {
mylog(log_debug, "cipher_encrypt failed ");
return -1;
}
return 0;
}
int my_decrypt(const char *data,char *output,int &len,char * key)
{
if(len<0) return -1;
if(len>max_data_len) {mylog(log_warn,"len>max_data_len");return -1;}
if(cipher_decrypt(data,output,len,key) !=0) {mylog(log_debug,"cipher_decrypt failed \n"); return -1;}
if(auth_verify(output,len)!=0) {mylog(log_debug,"auth_verify failed\n");return -1;}
int my_decrypt(const char *data, char *output, int &len /*,char * key*/) {
if (len < 0) return -1;
if (len > max_data_len) {
mylog(log_warn, "len>max_data_len");
return -1;
}
if (is_hmac_used)
return decrypt_AE(data, output, len);
if (cipher_decrypt(data, output, len, normal_key) != 0) {
mylog(log_debug, "cipher_decrypt failed \n");
return -1;
}
if (auth_verify(output, len) != 0) {
mylog(log_debug, "auth_verify failed\n");
return -1;
}
return 0;
}
int my_encrypt_old(const char *data0,char *output,int &len,char * key)
{
static const int disable_all=0;
static const int disable_aes=0;
char data[buf_len];
memcpy(data,data0,len);
if(disable_all)
{
memcpy(output,data,len);
return 0;
}
int ori_len=len;
len=len+16;//md5
len+=2;//length
if(len%16!=0)
{
len= (len/16)*16+16;
}
if(len>max_data_len) return -1;
data[len-16-2]= (unsigned char)( (uint16_t(ori_len))>>8);
data[len-16-1]=(unsigned char)( ((uint16_t(ori_len))<<8)>>8) ;
//printf("%d %d\n",data[len-16-2],data[len-16-1]);
md5((unsigned char *)data,len-16,(unsigned char *)(data+len-16));
if(disable_aes)
{
memcpy(output,data,len);
}
else
{
AES_CBC_encrypt_buffer((unsigned char *)output,(unsigned char *)data,len,(unsigned char *)key,(unsigned char *)zero_iv);
//it doesnt allow over lap
}
return 0;
}
int my_decrypt_old(const char *data0,char *output,int &len,char * key)
{
static const int disable_all=0;
static const int disable_aes=0;
char data[buf_len];
memcpy(data,data0,len);
if(disable_all)
{
memcpy(output,data,len);
return 0;
}
uint8_t md5_res[16];
if(len>max_data_len) return -1;
if(len<32) return -1;
if(len%16 !=0) return -1;
if(disable_aes)
{
memcpy(output,data,len);
}
else
{
AES_CBC_decrypt_buffer((unsigned char *)output,(unsigned char *)data,len,(unsigned char *)key,(unsigned char *)zero_iv);
}
//printf("%d %d\n",data[len-16-2],data[len-16-1]);
//printf("<<%d>>",len);
md5((unsigned char *)output,len-16,(unsigned char *)md5_res);
if(memcmp(output+len-16,md5_res,16)!=0)
{
return -2;
}
len=((unsigned char)output[len-16-2])*256u+((unsigned char)output[len-16-1]); //this may be broken because of sign
return 0;
int encrypt_AEAD(uint8_t *data, uint8_t *output, int &len, uint8_t *key, uint8_t *header, int hlen) {
// TODO
return -1;
}
int my_encrypt_pesudo_header(uint8_t *data,uint8_t *output,int &len,uint8_t * key,uint8_t *header,int hlen)
{
return 0;
int decrypt_AEAD(uint8_t *data, uint8_t *output, int &len, uint8_t *key, uint8_t *header, int hlen) {
// TODO
return -1;
}
int my_decrypt_pesudo_header(uint8_t *data,uint8_t *output,int &len,uint8_t * key,uint8_t *header,int hlen)
{
return 0;
}

52
encrypt.h Executable file → Normal file
View File

@ -1,39 +1,51 @@
#ifndef _ENCRYPTION_H_
#define _ENCRYPTION_H_
#ifndef UDP2RAW_ENCRYPTION_H_
#define UDP2RAW_ENCRYPTION_H_
//#include "aes.h"
//#include "md5.h"
#include "common.h"
// using namespace std;
// extern char key[16];
//using namespace std;
const int aes_key_optimize = 1; // if enabled,once you used a key for aes,you cant change it anymore
extern int aes128cfb_old;
int my_encrypt(const char *data,char *output,int &len,char * key);
int my_decrypt(const char *data,char *output,int &len,char * key);
int my_init_keys(const char *, int);
int my_encrypt_pesudo_header(uint8_t *data,uint8_t *output,int &len,uint8_t * key,uint8_t *header,int hlen);
int my_decrypt_pesudo_header(uint8_t *data,uint8_t *output,int &len,uint8_t * key,uint8_t *header,int hlen);
int my_encrypt(const char *data, char *output, int &len);
int my_decrypt(const char *data, char *output, int &len);
unsigned short csum(const unsigned short *ptr, int nbytes);
unsigned short csum(const unsigned short *ptr,int nbytes) ;
enum auth_mode_t {auth_none=0,auth_md5,auth_crc32,auth_simple,auth_end};
enum cipher_mode_t {cipher_none=0,cipher_aes128cbc,cipher_xor,cipher_end};
enum auth_mode_t { auth_none = 0,
auth_md5,
auth_crc32,
auth_simple,
auth_hmac_sha1,
auth_end };
enum cipher_mode_t { cipher_none = 0,
cipher_aes128cbc,
cipher_xor,
cipher_aes128cfb,
cipher_end };
extern auth_mode_t auth_mode;
extern cipher_mode_t cipher_mode;
struct a
{
char * buf[buf_len];
};
extern unordered_map<int, const char *> auth_mode_tostring;
extern unordered_map<int, const char *> cipher_mode_tostring;
extern char gro_xor[256 + 100];
int cipher_decrypt(const char *data, char *output, int &len, char *key); // internal interface ,exposed for test only
int cipher_encrypt(const char *data, char *output, int &len, char *key); // internal interface ,exposed for test only
void aes_ecb_encrypt(const char *data, char *output);
void aes_ecb_decrypt(const char *data, char *output);
void aes_ecb_encrypt1(char *data);
void aes_ecb_decrypt1(char *data);
#endif

16
example.conf Normal file
View File

@ -0,0 +1,16 @@
# Basically this file is the equivalent to splitting the command line options into multiple lines
# Each line should contain an option
# This is client
-c
# Or use -s if you use it on server side
# Define local address
-l 127.0.0.1:56789
# Define remote address
-r 45.66.77.88:45678
# Password
-k my_awesome_password
# Mode
--raw-mode faketcp
# Log Level
--log-level 4

53
fd_manager.cpp Normal file
View File

@ -0,0 +1,53 @@
/*
* fd_manager.cpp
*
* Created on: Sep 25, 2017
* Author: root
*/
#include "fd_manager.h"
int fd_manager_t::fd_exist(int fd) {
return fd_to_fd64_mp.find(fd) != fd_to_fd64_mp.end();
}
int fd_manager_t::exist(fd64_t fd64) {
return fd64_to_fd_mp.find(fd64) != fd64_to_fd_mp.end();
}
int fd_manager_t::to_fd(fd64_t fd64) {
assert(exist(fd64));
return fd64_to_fd_mp[fd64];
}
void fd_manager_t::fd64_close(fd64_t fd64) {
assert(exist(fd64));
int fd = fd64_to_fd_mp[fd64];
fd64_to_fd_mp.erase(fd64);
fd_to_fd64_mp.erase(fd);
if (exist_info(fd64)) {
fd_info_mp.erase(fd64);
}
// assert(close(fd)==0);
sock_close(fd);
}
void fd_manager_t::reserve(int n) {
fd_to_fd64_mp.reserve(n);
fd64_to_fd_mp.reserve(n);
fd_info_mp.reserve(n);
}
u64_t fd_manager_t::create(int fd) {
assert(!fd_exist(fd));
fd64_t fd64 = counter++;
fd_to_fd64_mp[fd] = fd64;
fd64_to_fd_mp[fd64] = fd;
return fd64;
}
fd_manager_t::fd_manager_t() {
counter = u32_t(-1);
counter += 100;
reserve(10007);
}
fd_info_t& fd_manager_t::get_info(fd64_t fd64) {
assert(exist(fd64));
return fd_info_mp[fd64];
}
int fd_manager_t::exist_info(fd64_t fd64) {
return fd_info_mp.find(fd64) != fd_info_mp.end();
}

43
fd_manager.h Normal file
View File

@ -0,0 +1,43 @@
/*
* fd_manager.h
*
* Created on: Sep 25, 2017
* Author: root
*/
#ifndef FD_MANAGER_H_
#define FD_MANAGER_H_
#include "common.h"
//#include "packet.h"
#include "connection.h"
struct fd_info_t {
// ip_port_t ip_port;
conn_info_t *p_conn_info;
};
struct fd_manager_t // conver fd to a uniq 64bit number,avoid fd value conflict caused by close and re-create
// this class is not strictly necessary,it just makes epoll fd handling easier
{
fd_info_t &get_info(fd64_t fd64);
int exist_info(fd64_t);
int exist(fd64_t fd64);
int to_fd(fd64_t);
void fd64_close(fd64_t fd64);
void reserve(int n);
u64_t create(int fd);
fd_manager_t();
private:
u64_t counter;
unordered_map<int, fd64_t> fd_to_fd64_mp;
unordered_map<fd64_t, int> fd64_to_fd_mp;
unordered_map<fd64_t, fd_info_t> fd_info_mp;
int fd_exist(int fd);
// void remove_fd(int fd);
// fd64_t fd_to_fd64(int fd);
};
extern fd_manager_t fd_manager;
#endif /* FD_MANAGER_H_ */

BIN
images/android.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 KiB

BIN
images/image0.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
images/image1.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
images/image2.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
images/image4.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
images/image5.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
images/lower_level.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
images/openvpn.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
images/output_client.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
images/output_server.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
images/route.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
images/speed_test.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

1
images/speedtest/111 Normal file
View File

@ -0,0 +1 @@

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

BIN
images/udp2rawopenvpn.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

1
images/wiki/111 Normal file
View File

@ -0,0 +1 @@

BIN
images/wiki/mac_nat_vb1.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
images/wiki/mac_nat_vb2.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

BIN
images/wiki/mac_nat_vb3.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
images/wiki/mac_nat_vb4.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
images/wiki/windows_nat.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

18
lib/aes-common.h Executable file
View File

@ -0,0 +1,18 @@
/*
* this file comes from https://github.com/kokke/tiny-AES128-C
*/
#pragma once
#include <stdint.h>
void AES_ECB_encrypt_buffer(const uint8_t* input, const uint8_t* key, uint8_t *output);
void AES_ECB_decrypt_buffer(const uint8_t* input, const uint8_t* key, uint8_t *output);
void AES_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv);
void AES_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv);
void AES_CFB_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv);
void AES_CFB_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv);

600
lib/aes.c
View File

@ -1,600 +0,0 @@
/*
* this file comes from https://github.com/kokke/tiny-AES128-C
*/
/*
This is an implementation of the AES algorithm, specifically ECB and CBC mode.
Block size can be chosen in aes.h - available choices are AES128, AES192, AES256.
The implementation is verified against the test vectors in:
National Institute of Standards and Technology Special Publication 800-38A 2001 ED
ECB-AES128
----------
plain-text:
6bc1bee22e409f96e93d7e117393172a
ae2d8a571e03ac9c9eb76fac45af8e51
30c81c46a35ce411e5fbc1191a0a52ef
f69f2445df4f9b17ad2b417be66c3710
key:
2b7e151628aed2a6abf7158809cf4f3c
resulting cipher
3ad77bb40d7a3660a89ecaf32466ef97
f5d3d58503b9699de785895a96fdbaaf
43b1cd7f598ece23881b00e3ed030688
7b0c785e27e8ad3f8223207104725dd4
NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
You should pad the end of the string with zeros if this is not the case.
For AES192/256 the block size is proportionally larger.
*/
/*****************************************************************************/
/* Includes: */
/*****************************************************************************/
#include <stdint.h>
#include <string.h> // CBC mode, for memset
#include "aes.h"
/*****************************************************************************/
/* Defines: */
/*****************************************************************************/
// The number of columns comprising a state in AES. This is a constant in AES. Value=4
#define Nb 4
#define BLOCKLEN 16 //Block length in bytes AES is 128b block only
#if defined(AES256) && (AES256 == 1)
#define Nk 8
#define KEYLEN 32
#define Nr 14
#define keyExpSize 240
#elif defined(AES192) && (AES192 == 1)
#define Nk 6
#define KEYLEN 24
#define Nr 12
#define keyExpSize 208
#else
#define Nk 4 // The number of 32 bit words in a key.
#define KEYLEN 16 // Key length in bytes
#define Nr 10 // The number of rounds in AES Cipher.
#define keyExpSize 176
#endif
// jcallan@github points out that declaring Multiply as a function
// reduces code size considerably with the Keil ARM compiler.
// See this link for more information: https://github.com/kokke/tiny-AES128-C/pull/3
#ifndef MULTIPLY_AS_A_FUNCTION
#define MULTIPLY_AS_A_FUNCTION 0
#endif
/*****************************************************************************/
/* Private variables: */
/*****************************************************************************/
// state - array holding the intermediate results during decryption.
typedef uint8_t state_t[4][4];
static state_t* state;
// The array that stores the round keys.
static uint8_t RoundKey[keyExpSize];
// The Key input to the AES Program
static const uint8_t* Key;
#if defined(CBC) && CBC
// Initial Vector used only for CBC mode
static uint8_t* Iv;
#endif
// The lookup-tables are marked const so they can be placed in read-only storage instead of RAM
// The numbers below can be computed dynamically trading ROM for RAM -
// This can be useful in (embedded) bootloader applications, where ROM is often limited.
static const uint8_t sbox[256] = {
//0 1 2 3 4 5 6 7 8 9 A B C D E F
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
static const uint8_t rsbox[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
// The round constant word array, Rcon[i], contains the values given by
// x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
static const uint8_t Rcon[11] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
/*
* Jordan Goulder points out in PR #12 (https://github.com/kokke/tiny-AES128-C/pull/12),
* that you can remove most of the elements in the Rcon array, because they are unused.
*
* From Wikipedia's article on the Rijndael key schedule @ https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon
*
* "Only the first some of these constants are actually used up to rcon[10] for AES-128 (as 11 round keys are needed),
* up to rcon[8] for AES-192, up to rcon[7] for AES-256. rcon[0] is not used in AES algorithm."
*
* ... which is why the full array below has been 'disabled' below.
*/
#if 0
static const uint8_t Rcon[256] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d };
#endif
/*****************************************************************************/
/* Private functions: */
/*****************************************************************************/
static uint8_t getSBoxValue(uint8_t num)
{
return sbox[num];
}
static uint8_t getSBoxInvert(uint8_t num)
{
return rsbox[num];
}
// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
static void KeyExpansion(void)
{
uint32_t i, k;
uint8_t tempa[4]; // Used for the column/row operations
// The first round key is the key itself.
for (i = 0; i < Nk; ++i)
{
RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
}
// All other round keys are found from the previous round keys.
//i == Nk
for (; i < Nb * (Nr + 1); ++i)
{
{
tempa[0]=RoundKey[(i-1) * 4 + 0];
tempa[1]=RoundKey[(i-1) * 4 + 1];
tempa[2]=RoundKey[(i-1) * 4 + 2];
tempa[3]=RoundKey[(i-1) * 4 + 3];
}
if (i % Nk == 0)
{
// This function shifts the 4 bytes in a word to the left once.
// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
// Function RotWord()
{
k = tempa[0];
tempa[0] = tempa[1];
tempa[1] = tempa[2];
tempa[2] = tempa[3];
tempa[3] = k;
}
// SubWord() is a function that takes a four-byte input word and
// applies the S-box to each of the four bytes to produce an output word.
// Function Subword()
{
tempa[0] = getSBoxValue(tempa[0]);
tempa[1] = getSBoxValue(tempa[1]);
tempa[2] = getSBoxValue(tempa[2]);
tempa[3] = getSBoxValue(tempa[3]);
}
tempa[0] = tempa[0] ^ Rcon[i/Nk];
}
#if defined(AES256) && (AES256 == 1)
if (i % Nk == 4)
{
// Function Subword()
{
tempa[0] = getSBoxValue(tempa[0]);
tempa[1] = getSBoxValue(tempa[1]);
tempa[2] = getSBoxValue(tempa[2]);
tempa[3] = getSBoxValue(tempa[3]);
}
}
#endif
RoundKey[i * 4 + 0] = RoundKey[(i - Nk) * 4 + 0] ^ tempa[0];
RoundKey[i * 4 + 1] = RoundKey[(i - Nk) * 4 + 1] ^ tempa[1];
RoundKey[i * 4 + 2] = RoundKey[(i - Nk) * 4 + 2] ^ tempa[2];
RoundKey[i * 4 + 3] = RoundKey[(i - Nk) * 4 + 3] ^ tempa[3];
}
}
// This function adds the round key to state.
// The round key is added to the state by an XOR function.
static void AddRoundKey(uint8_t round)
{
uint8_t i,j;
for (i=0;i<4;++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[i][j] ^= RoundKey[round * Nb * 4 + i * Nb + j];
}
}
}
// The SubBytes Function Substitutes the values in the
// state matrix with values in an S-box.
static void SubBytes(void)
{
uint8_t i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[j][i] = getSBoxValue((*state)[j][i]);
}
}
}
// The ShiftRows() function shifts the rows in the state to the left.
// Each row is shifted with different offset.
// Offset = Row number. So the first row is not shifted.
static void ShiftRows(void)
{
uint8_t temp;
// Rotate first row 1 columns to left
temp = (*state)[0][1];
(*state)[0][1] = (*state)[1][1];
(*state)[1][1] = (*state)[2][1];
(*state)[2][1] = (*state)[3][1];
(*state)[3][1] = temp;
// Rotate second row 2 columns to left
temp = (*state)[0][2];
(*state)[0][2] = (*state)[2][2];
(*state)[2][2] = temp;
temp = (*state)[1][2];
(*state)[1][2] = (*state)[3][2];
(*state)[3][2] = temp;
// Rotate third row 3 columns to left
temp = (*state)[0][3];
(*state)[0][3] = (*state)[3][3];
(*state)[3][3] = (*state)[2][3];
(*state)[2][3] = (*state)[1][3];
(*state)[1][3] = temp;
}
static uint8_t xtime(uint8_t x)
{
return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
}
// MixColumns function mixes the columns of the state matrix
static void MixColumns(void)
{
uint8_t i;
uint8_t Tmp,Tm,t;
for (i = 0; i < 4; ++i)
{
t = (*state)[i][0];
Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;
Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ;
Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ;
Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ;
Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ;
}
}
// Multiply is used to multiply numbers in the field GF(2^8)
#if MULTIPLY_AS_A_FUNCTION
static uint8_t Multiply(uint8_t x, uint8_t y)
{
return (((y & 1) * x) ^
((y>>1 & 1) * xtime(x)) ^
((y>>2 & 1) * xtime(xtime(x))) ^
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^
((y>>4 & 1) * xtime(xtime(xtime(xtime(x))))));
}
#else
#define Multiply(x, y) \
( ((y & 1) * x) ^ \
((y>>1 & 1) * xtime(x)) ^ \
((y>>2 & 1) * xtime(xtime(x))) ^ \
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \
#endif
// MixColumns function mixes the columns of the state matrix.
// The method used to multiply may be difficult to understand for the inexperienced.
// Please use the references to gain more information.
static void InvMixColumns(void)
{
int i;
uint8_t a, b, c, d;
for (i = 0; i < 4; ++i)
{
a = (*state)[i][0];
b = (*state)[i][1];
c = (*state)[i][2];
d = (*state)[i][3];
(*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
(*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
(*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
(*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
}
}
// The SubBytes Function Substitutes the values in the
// state matrix with values in an S-box.
static void InvSubBytes(void)
{
uint8_t i,j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[j][i] = getSBoxInvert((*state)[j][i]);
}
}
}
static void InvShiftRows(void)
{
uint8_t temp;
// Rotate first row 1 columns to right
temp = (*state)[3][1];
(*state)[3][1] = (*state)[2][1];
(*state)[2][1] = (*state)[1][1];
(*state)[1][1] = (*state)[0][1];
(*state)[0][1] = temp;
// Rotate second row 2 columns to right
temp = (*state)[0][2];
(*state)[0][2] = (*state)[2][2];
(*state)[2][2] = temp;
temp = (*state)[1][2];
(*state)[1][2] = (*state)[3][2];
(*state)[3][2] = temp;
// Rotate third row 3 columns to right
temp = (*state)[0][3];
(*state)[0][3] = (*state)[1][3];
(*state)[1][3] = (*state)[2][3];
(*state)[2][3] = (*state)[3][3];
(*state)[3][3] = temp;
}
// Cipher is the main function that encrypts the PlainText.
static void Cipher(void)
{
uint8_t round = 0;
// Add the First round key to the state before starting the rounds.
AddRoundKey(0);
// There will be Nr rounds.
// The first Nr-1 rounds are identical.
// These Nr-1 rounds are executed in the loop below.
for (round = 1; round < Nr; ++round)
{
SubBytes();
ShiftRows();
MixColumns();
AddRoundKey(round);
}
// The last round is given below.
// The MixColumns function is not here in the last round.
SubBytes();
ShiftRows();
AddRoundKey(Nr);
}
static void InvCipher(void)
{
uint8_t round=0;
// Add the First round key to the state before starting the rounds.
AddRoundKey(Nr);
// There will be Nr rounds.
// The first Nr-1 rounds are identical.
// These Nr-1 rounds are executed in the loop below.
for (round = (Nr - 1); round > 0; --round)
{
InvShiftRows();
InvSubBytes();
AddRoundKey(round);
InvMixColumns();
}
// The last round is given below.
// The MixColumns function is not here in the last round.
InvShiftRows();
InvSubBytes();
AddRoundKey(0);
}
/*****************************************************************************/
/* Public functions: */
/*****************************************************************************/
#if defined(ECB) && (ECB == 1)
void AES_ECB_encrypt(const uint8_t* input, const uint8_t* key, uint8_t* output, const uint32_t length)
{
// Copy input to output, and work in-memory on output
memcpy(output, input, length);
state = (state_t*)output;
Key = key;
KeyExpansion();
// The next function call encrypts the PlainText with the Key using AES algorithm.
Cipher();
}
void AES_ECB_decrypt(const uint8_t* input, const uint8_t* key, uint8_t *output, const uint32_t length)
{
// Copy input to output, and work in-memory on output
memcpy(output, input, length);
state = (state_t*)output;
// The KeyExpansion routine must be called before encryption.
Key = key;
KeyExpansion();
InvCipher();
}
#endif // #if defined(ECB) && (ECB == 1)
#if defined(CBC) && (CBC == 1)
static void XorWithIv(uint8_t* buf)
{
uint8_t i;
for (i = 0; i < BLOCKLEN; ++i) //WAS for(i = 0; i < KEYLEN; ++i) but the block in AES is always 128bit so 16 bytes!
{
buf[i] ^= Iv[i];
}
}
void AES_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
{
uintptr_t i;
uint8_t extra = length % BLOCKLEN; /* Remaining bytes in the last non-full block */
// Skip the key expansion if key is passed as 0
if (0 != key)
{
Key = key;
KeyExpansion();
}
if (iv != 0)
{
Iv = (uint8_t*)iv;
}
for (i = 0; i < length; i += BLOCKLEN)
{
XorWithIv(input);
memcpy(output, input, BLOCKLEN);
state = (state_t*)output;
Cipher();
Iv = output;
input += BLOCKLEN;
output += BLOCKLEN;
//printf("Step %d - %d", i/16, i);
}
if (extra)
{
memcpy(output, input, extra);
state = (state_t*)output;
Cipher();
}
}
void AES_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
{
uintptr_t i;
uint8_t extra = length % BLOCKLEN; /* Remaining bytes in the last non-full block */
// Skip the key expansion if key is passed as 0
if (0 != key)
{
Key = key;
KeyExpansion();
}
// If iv is passed as 0, we continue to encrypt without re-setting the Iv
if (iv != 0)
{
Iv = (uint8_t*)iv;
}
for (i = 0; i < length; i += BLOCKLEN)
{
memcpy(output, input, BLOCKLEN);
state = (state_t*)output;
InvCipher();
XorWithIv(output);
Iv = input;
input += BLOCKLEN;
output += BLOCKLEN;
}
if (extra)
{
memcpy(output, input, extra);
state = (state_t*)output;
InvCipher();
}
}
#endif // #if defined(CBC) && (CBC == 1)

View File

@ -1,45 +0,0 @@
/*
* this file comes from https://github.com/kokke/tiny-AES128-C
*/
#ifndef _AES_H_
#define _AES_H_
#include <stdint.h>
// #define the macros below to 1/0 to enable/disable the mode of operation.
//
// CBC enables AES encryption in CBC-mode of operation.
// ECB enables the basic ECB 16-byte block algorithm. Both can be enabled simultaneously.
// The #ifndef-guard allows it to be configured before #include'ing or at compile time.
#ifndef CBC
#define CBC 1
#endif
#ifndef ECB
#define ECB 1
#endif
#define AES128 1
//#define AES192 1
//#define AES256 1
#if defined(ECB) && (ECB == 1)
void AES_ECB_encrypt(const uint8_t* input, const uint8_t* key, uint8_t *output, const uint32_t length);
void AES_ECB_decrypt(const uint8_t* input, const uint8_t* key, uint8_t *output, const uint32_t length);
#endif // #if defined(ECB) && (ECB == !)
#if defined(CBC) && (CBC == 1)
void AES_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv);
void AES_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv);
#endif // #if defined(CBC) && (CBC == 1)
#endif //_AES_H_

462
lib/aes_acc/aesacc.c Normal file
View File

@ -0,0 +1,462 @@
/*
* This file is adapted from PolarSSL 1.3.19 (GPL)
*/
#include "aesni.h"
#include "aesarm.h"
#include <stdint.h>
#include <string.h>
#include <assert.h>
#if defined(AES256) && (AES256 == 1)
#define AES_KEYSIZE 256
#ifdef HAVE_AMD64
#define aeshw_setkey_enc aesni_setkey_enc_256
#endif
#elif defined(AES192) && (AES192 == 1)
#define AES_KEYSIZE 192
#ifdef HAVE_AMD64
#define aeshw_setkey_enc aesni_setkey_enc_192
#endif
#else
#define AES_KEYSIZE 128
#ifdef HAVE_AMD64
#define aeshw_setkey_enc aesni_setkey_enc_128
#endif
#endif
#define AES_NR ((AES_KEYSIZE >> 5) + 6)
#define AES_RKSIZE 272
#ifdef HAVE_AMD64
#define HAVE_HARDAES 1
#define aeshw_supported aesni_supported
#define aeshw_crypt_ecb aesni_crypt_ecb
#define aeshw_inverse_key(a,b) aesni_inverse_key(a,b,AES_NR)
#endif /* HAVE_AMD64 */
#ifdef HAVE_ARM64
#define HAVE_HARDAES 1
#define aeshw_supported aesarm_supported
#define aeshw_crypt_ecb aesarm_crypt_ecb
#include "aesarm_table.h"
#ifndef GET_UINT32_LE
#define GET_UINT32_LE(n,b,i) \
{ \
(n) = ( (uint32_t) (b)[(i) ] ) \
| ( (uint32_t) (b)[(i) + 1] << 8 ) \
| ( (uint32_t) (b)[(i) + 2] << 16 ) \
| ( (uint32_t) (b)[(i) + 3] << 24 ); \
}
#endif
static void aeshw_setkey_enc(uint8_t *rk, const uint8_t *key)
{
unsigned int i;
uint32_t *RK;
RK = (uint32_t *) rk;
for( i = 0; i < ( AES_KEYSIZE >> 5 ); i++ )
{
GET_UINT32_LE( RK[i], key, i << 2 );
}
switch( AES_NR )
{
case 10:
for( i = 0; i < 10; i++, RK += 4 )
{
RK[4] = RK[0] ^ RCON[i] ^
( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^
( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^
( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 );
RK[5] = RK[1] ^ RK[4];
RK[6] = RK[2] ^ RK[5];
RK[7] = RK[3] ^ RK[6];
}
break;
case 12:
for( i = 0; i < 8; i++, RK += 6 )
{
RK[6] = RK[0] ^ RCON[i] ^
( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^
( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^
( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 );
RK[7] = RK[1] ^ RK[6];
RK[8] = RK[2] ^ RK[7];
RK[9] = RK[3] ^ RK[8];
RK[10] = RK[4] ^ RK[9];
RK[11] = RK[5] ^ RK[10];
}
break;
case 14:
for( i = 0; i < 7; i++, RK += 8 )
{
RK[8] = RK[0] ^ RCON[i] ^
( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^
( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^
( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 );
RK[9] = RK[1] ^ RK[8];
RK[10] = RK[2] ^ RK[9];
RK[11] = RK[3] ^ RK[10];
RK[12] = RK[4] ^
( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^
( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
RK[13] = RK[5] ^ RK[12];
RK[14] = RK[6] ^ RK[13];
RK[15] = RK[7] ^ RK[14];
}
break;
}
}
static void aeshw_inverse_key(uint8_t *invkey, const uint8_t *fwdkey)
{
int i, j;
uint32_t *RK;
uint32_t *SK;
RK = (uint32_t *) invkey;
SK = ((uint32_t *) fwdkey) + AES_NR * 4;
*RK++ = *SK++;
*RK++ = *SK++;
*RK++ = *SK++;
*RK++ = *SK++;
for( i = AES_NR - 1, SK -= 8; i > 0; i--, SK -= 8 )
{
for( j = 0; j < 4; j++, SK++ )
{
*RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^
RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^
RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^
RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ];
}
}
*RK++ = *SK++;
*RK++ = *SK++;
*RK++ = *SK++;
*RK++ = *SK++;
}
#endif /* HAVE_ARM64 */
#ifdef HAVE_HARDAES
static void aeshw_setkey_dec(uint8_t *rk, const uint8_t *key)
{
uint8_t rk_tmp[AES_RKSIZE];
aeshw_setkey_enc(rk_tmp, key);
aeshw_inverse_key(rk, rk_tmp);
}
static void aeshw_encrypt_ecb( int nr,
unsigned char *rk,
const unsigned char input[16],
unsigned char output[16] )
{
aeshw_crypt_ecb(nr, rk, AES_ENCRYPT, input, output);
}
static void aeshw_decrypt_ecb( int nr,
unsigned char *rk,
const unsigned char input[16],
unsigned char output[16] )
{
aeshw_crypt_ecb(nr, rk, AES_DECRYPT, input, output);
}
#endif /* HAVE_HARDAES */
/* OpenSSL assembly functions */
#define AES_MAXNR 14
typedef struct {
uint32_t rd_key[4 * (AES_MAXNR + 1)];
uint32_t rounds;
} AES_KEY;
#if defined(__amd64__) || defined(__x86_64__) || \
defined(__aarch64__)
#define AES_set_encrypt_key vpaes_set_encrypt_key
#define AES_set_decrypt_key vpaes_set_decrypt_key
#define AES_encrypt vpaes_encrypt
#define AES_decrypt vpaes_decrypt
#endif /* VPAES for 64-bit Intel and ARM */
#ifdef __cplusplus
extern "C" {
#endif
int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
void AES_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void AES_decrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
#ifdef __cplusplus
}
#endif
static void aes_encrypt_ecb( int nr,
unsigned char *rk,
const unsigned char input[16],
unsigned char output[16] )
{
AES_encrypt(input, output, (AES_KEY *) rk);
}
static void aes_decrypt_ecb( int nr,
unsigned char *rk,
const unsigned char input[16],
unsigned char output[16] )
{
AES_decrypt(input, output, (AES_KEY *) rk);
}
static void aes_setkey_enc(uint8_t *rk, const uint8_t *key)
{
AES_set_encrypt_key(key, AES_KEYSIZE, (AES_KEY *) rk);
}
static void aes_setkey_dec(uint8_t *rk, const uint8_t *key)
{
AES_set_decrypt_key(key, AES_KEYSIZE, (AES_KEY *) rk);
}
static void (*encrypt_ecb) ( int nr,
unsigned char *rk,
const unsigned char input[16],
unsigned char output[16] )
= aes_encrypt_ecb;
static void (*decrypt_ecb) ( int nr,
unsigned char *rk,
const unsigned char input[16],
unsigned char output[16] )
= aes_decrypt_ecb;
static void (*setkey_enc) (uint8_t *rk, const uint8_t *key)
= aes_setkey_enc;
static void (*setkey_dec) (uint8_t *rk, const uint8_t *key)
= aes_setkey_dec;
/*
* AESNI-CBC buffer encryption/decryption
*/
static void encrypt_cbc( uint8_t* rk,
uint32_t length,
uint8_t iv[16],
const uint8_t *input,
uint8_t *output )
{
int i;
uint8_t temp[16];
while( length > 0 )
{
for( i = 0; i < 16; i++ )
output[i] = (uint8_t)( input[i] ^ iv[i] );
encrypt_ecb( AES_NR, rk, output, output );
memcpy( iv, output, 16 );
input += 16;
output += 16;
length -= 16;
}
}
static void decrypt_cbc( uint8_t* rk,
uint32_t length,
uint8_t iv[16],
const uint8_t *input,
uint8_t *output )
{
int i;
uint8_t temp[16];
while( length > 0 )
{
memcpy( temp, input, 16 );
decrypt_ecb( AES_NR, rk, input, output );
for( i = 0; i < 16; i++ )
output[i] = (uint8_t)( output[i] ^ iv[i] );
memcpy( iv, temp, 16 );
input += 16;
output += 16;
length -= 16;
}
}
static void aeshw_init(void)
{
#ifdef HAVE_HARDAES
static int done = 0;
if (!done) {
if (aeshw_supported()) {
encrypt_ecb = aeshw_encrypt_ecb;
decrypt_ecb = aeshw_decrypt_ecb;
setkey_enc = aeshw_setkey_enc;
setkey_dec = aeshw_setkey_dec;
}
done = 1;
}
#endif
}
int AES_support_hwaccel(void)
{
#ifdef HAVE_HARDAES
return aeshw_supported();
#else
return 0;
#endif
}
void AES_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
{
uint8_t iv_tmp[16];
static uint8_t rk[AES_RKSIZE];
assert(iv!=NULL);
aeshw_init();
memcpy(iv_tmp, iv, 16);
if(key!= NULL)
setkey_enc(rk, key);
encrypt_cbc(rk, length, iv_tmp, input, output);
}
void AES_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
{
uint8_t iv_tmp[16];
static uint8_t rk[AES_RKSIZE];
assert(iv!=NULL);
aeshw_init();
memcpy(iv_tmp, iv, 16);
if(key!= NULL)
{
setkey_dec(rk, key);
}
decrypt_cbc(rk, length, iv_tmp, input, output);
}
void AES_ECB_encrypt_buffer(const uint8_t* input, const uint8_t* key, uint8_t* output)
{
static uint8_t rk[AES_RKSIZE];
aeshw_init();
if(key!=NULL)
setkey_enc(rk, key);
encrypt_ecb(AES_NR, rk, input, output);
}
void AES_ECB_decrypt_buffer(const uint8_t* input, const uint8_t* key, uint8_t *output)
{
static uint8_t rk[AES_RKSIZE];
aeshw_init();
if(key!=NULL)
setkey_dec(rk, key);
decrypt_ecb(AES_NR, rk, input, output);
}
static void encrypt_cfb( uint8_t* rk,
uint32_t length,size_t *iv_off,
uint8_t iv[16],
const uint8_t *input,
uint8_t *output )
{
int c;
size_t n = *iv_off;
while( length-- )
{
if( n == 0 )
encrypt_ecb( AES_NR, rk, iv, iv );
iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
n = ( n + 1 ) & 0x0F;
}
*iv_off = n;
}
static void decrypt_cfb( uint8_t* rk,
uint32_t length,size_t *iv_off,
uint8_t iv[16],
const uint8_t *input,
uint8_t *output )
{
int c;
size_t n = *iv_off;
while( length-- )
{
if( n == 0 )
encrypt_ecb( AES_NR, rk, iv, iv );
c = *input++;
*output++ = (unsigned char)( c ^ iv[n] );
iv[n] = (unsigned char) c;
n = ( n + 1 ) & 0x0F;
}
*iv_off = n;
}
void AES_CFB_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
{
uint8_t iv_tmp[16];
static uint8_t rk[AES_RKSIZE];
assert(iv!=NULL);
aeshw_init();
memcpy(iv_tmp, iv, 16);
if(key!= NULL)
setkey_enc(rk, key);
size_t offset=0;
encrypt_cfb(rk, length,&offset, iv_tmp, input, output);
}
void AES_CFB_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
{
uint8_t iv_tmp[16];
static uint8_t rk[AES_RKSIZE];
assert(iv!=NULL);
aeshw_init();
memcpy(iv_tmp, iv, 16);
if(key!= NULL)
{
setkey_enc(rk, key);//its enc again,not typo
}
size_t offset=0;
decrypt_cfb(rk, length,&offset, iv_tmp, input, output);
}

115
lib/aes_acc/aesarm.c Normal file
View File

@ -0,0 +1,115 @@
/*
* This file is adapted from https://github.com/CriticalBlue/mbedtls
*/
/*
* ARMv8-A Cryptography Extension AES support functions
*
* Copyright (C) 2016, CriticalBlue Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#include "aesarm.h"
#if defined(HAVE_ARM64)
#include <sys/auxv.h>
#include <asm/hwcap.h>
#include <arm_neon.h>
/*
* ARMv8a Crypto Extension support detection routine
*/
int aesarm_supported( void )
{
static int done = 0;
static unsigned int c = 0;
if ( ! done )
{
c = getauxval(AT_HWCAP);
done = 1;
}
return ( c & HWCAP_AES ) != 0;
}
/*
* ARMv8a AES-ECB block en(de)cryption
*/
void aesarm_crypt_ecb( int nr,
unsigned char *rk,
int mode,
const unsigned char input[16],
unsigned char output[16] )
{
int i;
uint8x16_t state_vec, roundkey_vec;
uint8_t *RK = (uint8_t *) rk;
// Load input and round key into into their vectors
state_vec = vld1q_u8( input );
if ( mode == AES_ENCRYPT )
{
// Initial AddRoundKey is in the loop due to AES instruction always doing AddRoundKey first
for( i = 0; i < nr - 1; i++ )
{
// Load Round Key
roundkey_vec = vld1q_u8( RK );
// Forward (AESE) round (AddRoundKey, SubBytes and ShiftRows)
state_vec = vaeseq_u8( state_vec, roundkey_vec );
// Mix Columns (AESMC)
state_vec = vaesmcq_u8( state_vec );
// Move pointer ready to load next round key
RK += 16;
}
// Final Forward (AESE) round (AddRoundKey, SubBytes and ShiftRows). No Mix columns
roundkey_vec = vld1q_u8( RK ); /* RK already moved in loop */
state_vec = vaeseq_u8( state_vec, roundkey_vec );
}
else
{
// Initial AddRoundKey is in the loop due to AES instruction always doing AddRoundKey first
for( i = 0; i < nr - 1; i++ )
{
// Load Round Key
roundkey_vec = vld1q_u8( RK );
// Reverse (AESD) round (AddRoundKey, SubBytes and ShiftRows)
state_vec = vaesdq_u8( state_vec, roundkey_vec );
// Inverse Mix Columns (AESIMC)
state_vec = vaesimcq_u8( state_vec );
// Move pointer ready to load next round key
RK += 16;
}
// Final Reverse (AESD) round (AddRoundKey, SubBytes and ShiftRows). No Mix columns
roundkey_vec = vld1q_u8( RK ); /* RK already moved in loop */
state_vec = vaesdq_u8( state_vec, roundkey_vec );
}
// Manually apply final Add RoundKey step (EOR)
RK += 16;
roundkey_vec = vld1q_u8( RK );
state_vec = veorq_u8( state_vec, roundkey_vec );
// Write results back to output array
vst1q_u8( output, state_vec );
}
#endif /* HAVE_ARM64 */

84
lib/aes_acc/aesarm.h Normal file
View File

@ -0,0 +1,84 @@
/*
* This file is adapted from https://github.com/CriticalBlue/mbedtls
*/
/**
* \file aes_armv8a_ce.h
*
* \brief AES support functions using the ARMv8-A Cryptography Extension for
* hardware acceleration on some ARM processors.
*
* Copyright (C) 2016, CriticalBlue Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef UDP2RAW_AESARM_H_
#define UDP2RAW_AESARM_H_
#ifndef AES_ENCRYPT
#define AES_ENCRYPT 1
#endif
#ifndef AES_DECRYPT
#define AES_DECRYPT 0
#endif
#if defined(__GNUC__) && \
__ARM_ARCH >= 8 && \
__ARM_ARCH_PROFILE == 'A' && \
defined(__aarch64__) && \
defined(__ARM_FEATURE_CRYPTO) && \
defined(__linux__) && \
!defined(NO_AESACC)
#define HAVE_ARM64
#endif
#if defined(HAVE_ARM64)
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief ARMv8-A features detection routine
*
* \return 1 if the CPU has support for the feature, 0 otherwise
*/
int aesarm_supported( void );
/**
* \brief AES ARMv8-A Cryptography Extension AES-ECB block en(de)cryption
*
* \param nr number of rounds
* \param rk AES round keys
* \param mode AESARM_ENCRYPT or AESARM_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*/
void aesarm_crypt_ecb( int nr,
unsigned char *rk,
int mode,
const unsigned char input[16],
unsigned char output[16] );
#ifdef __cplusplus
}
#endif
#endif /* HAVE_ARM64 */
#endif /* _AESARM_H_ */

140
lib/aes_acc/aesarm_table.h Normal file
View File

@ -0,0 +1,140 @@
/*
* This file is adapted from PolarSSL 1.3.19 (GPL)
*/
/*
* Forward S-box
*/
static const unsigned char FSb[256] =
{
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
};
/*
* Round constants
*/
static const uint32_t RCON[10] =
{
0x00000001, 0x00000002, 0x00000004, 0x00000008,
0x00000010, 0x00000020, 0x00000040, 0x00000080,
0x0000001B, 0x00000036
};
/*
* Reverse tables
*/
#define RT \
\
V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \
V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \
V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \
V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \
V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \
V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \
V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \
V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \
V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \
V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \
V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \
V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \
V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \
V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \
V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \
V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \
V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \
V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \
V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \
V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \
V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \
V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \
V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \
V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \
V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \
V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \
V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \
V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \
V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \
V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \
V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \
V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \
V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \
V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \
V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \
V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \
V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \
V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \
V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \
V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \
V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \
V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \
V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \
V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \
V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \
V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \
V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \
V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \
V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \
V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \
V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \
V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \
V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \
V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \
V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \
V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \
V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \
V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \
V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \
V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \
V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \
V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \
V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \
V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0)
#define V(a,b,c,d) 0x##a##b##c##d
static const uint32_t RT0[256] = { RT };
#undef V
#define V(a,b,c,d) 0x##b##c##d##a
static const uint32_t RT1[256] = { RT };
#undef V
#define V(a,b,c,d) 0x##c##d##a##b
static const uint32_t RT2[256] = { RT };
#undef V
#define V(a,b,c,d) 0x##d##a##b##c
static const uint32_t RT3[256] = { RT };
#undef V
#undef RT

324
lib/aes_acc/aesni.c Normal file
View File

@ -0,0 +1,324 @@
/*
* This file is adapted from PolarSSL 1.3.19 (GPL)
*/
/*
* AES-NI support functions
*
* Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
*
* This file is part of mbed TLS (https://tls.mbed.org)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* [AES-WP] http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-aes-instructions-set
* [CLMUL-WP] http://software.intel.com/en-us/articles/intel-carry-less-multiplication-instruction-and-its-usage-for-computing-the-gcm-mode/
*/
#include <string.h>
#include "aesni.h"
#if defined(HAVE_AMD64)
/*
* AES-NI support detection routine
*/
#define AESNI_AES 0x02000000u
int aesni_supported( void )
{
static int done = 0;
static unsigned int c = 0;
if( ! done )
{
asm( "movl $1, %%eax \n\t"
"cpuid \n\t"
: "=c" (c)
:
: "eax", "ebx", "edx" );
done = 1;
}
return( ( c & AESNI_AES ) != 0 );
}
/*
* Binutils needs to be at least 2.19 to support AES-NI instructions.
* Unfortunately, a lot of users have a lower version now (2014-04).
* Emit bytecode directly in order to support "old" version of gas.
*
* Opcodes from the Intel architecture reference manual, vol. 3.
* We always use registers, so we don't need prefixes for memory operands.
* Operand macros are in gas order (src, dst) as opposed to Intel order
* (dst, src) in order to blend better into the surrounding assembly code.
*/
#define AESDEC ".byte 0x66,0x0F,0x38,0xDE,"
#define AESDECLAST ".byte 0x66,0x0F,0x38,0xDF,"
#define AESENC ".byte 0x66,0x0F,0x38,0xDC,"
#define AESENCLAST ".byte 0x66,0x0F,0x38,0xDD,"
#define AESIMC ".byte 0x66,0x0F,0x38,0xDB,"
#define AESKEYGENA ".byte 0x66,0x0F,0x3A,0xDF,"
#define PCLMULQDQ ".byte 0x66,0x0F,0x3A,0x44,"
#define xmm0_xmm0 "0xC0"
#define xmm0_xmm1 "0xC8"
#define xmm0_xmm2 "0xD0"
#define xmm0_xmm3 "0xD8"
#define xmm0_xmm4 "0xE0"
#define xmm1_xmm0 "0xC1"
#define xmm1_xmm2 "0xD1"
/*
* AES-NI AES-ECB block en(de)cryption
*/
void aesni_crypt_ecb( int nr,
unsigned char *rk,
int mode,
const unsigned char input[16],
unsigned char output[16] )
{
asm( "movdqu (%3), %%xmm0 \n\t" // load input
"movdqu (%1), %%xmm1 \n\t" // load round key 0
"pxor %%xmm1, %%xmm0 \n\t" // round 0
"addq $16, %1 \n\t" // point to next round key
"subl $1, %0 \n\t" // normal rounds = nr - 1
"test %2, %2 \n\t" // mode?
"jz 2f \n\t" // 0 = decrypt
"1: \n\t" // encryption loop
"movdqu (%1), %%xmm1 \n\t" // load round key
AESENC xmm1_xmm0 "\n\t" // do round
"addq $16, %1 \n\t" // point to next round key
"subl $1, %0 \n\t" // loop
"jnz 1b \n\t"
"movdqu (%1), %%xmm1 \n\t" // load round key
AESENCLAST xmm1_xmm0 "\n\t" // last round
"jmp 3f \n\t"
"2: \n\t" // decryption loop
"movdqu (%1), %%xmm1 \n\t"
AESDEC xmm1_xmm0 "\n\t" // do round
"addq $16, %1 \n\t"
"subl $1, %0 \n\t"
"jnz 2b \n\t"
"movdqu (%1), %%xmm1 \n\t" // load round key
AESDECLAST xmm1_xmm0 "\n\t" // last round
"3: \n\t"
"movdqu %%xmm0, (%4) \n\t" // export output
:
: "r" (nr), "r" (rk), "r" (mode), "r" (input), "r" (output)
: "memory", "cc", "xmm0", "xmm1" );
}
/*
* Compute decryption round keys from encryption round keys
*/
void aesni_inverse_key( unsigned char *invkey,
const unsigned char *fwdkey, int nr )
{
unsigned char *ik = invkey;
const unsigned char *fk = fwdkey + 16 * nr;
memcpy( ik, fk, 16 );
for( fk -= 16, ik += 16; fk > fwdkey; fk -= 16, ik += 16 )
asm( "movdqu (%0), %%xmm0 \n\t"
AESIMC xmm0_xmm0 "\n\t"
"movdqu %%xmm0, (%1) \n\t"
:
: "r" (fk), "r" (ik)
: "memory", "xmm0" );
memcpy( ik, fk, 16 );
}
/*
* Key expansion, 128-bit case
*/
void aesni_setkey_enc_128( unsigned char *rk,
const unsigned char *key )
{
asm( "movdqu (%1), %%xmm0 \n\t" // copy the original key
"movdqu %%xmm0, (%0) \n\t" // as round key 0
"jmp 2f \n\t" // skip auxiliary routine
/*
* Finish generating the next round key.
*
* On entry xmm0 is r3:r2:r1:r0 and xmm1 is X:stuff:stuff:stuff
* with X = rot( sub( r3 ) ) ^ RCON.
*
* On exit, xmm0 is r7:r6:r5:r4
* with r4 = X + r0, r5 = r4 + r1, r6 = r5 + r2, r7 = r6 + r3
* and those are written to the round key buffer.
*/
"1: \n\t"
"pshufd $0xff, %%xmm1, %%xmm1 \n\t" // X:X:X:X
"pxor %%xmm0, %%xmm1 \n\t" // X+r3:X+r2:X+r1:r4
"pslldq $4, %%xmm0 \n\t" // r2:r1:r0:0
"pxor %%xmm0, %%xmm1 \n\t" // X+r3+r2:X+r2+r1:r5:r4
"pslldq $4, %%xmm0 \n\t" // etc
"pxor %%xmm0, %%xmm1 \n\t"
"pslldq $4, %%xmm0 \n\t"
"pxor %%xmm1, %%xmm0 \n\t" // update xmm0 for next time!
"add $16, %0 \n\t" // point to next round key
"movdqu %%xmm0, (%0) \n\t" // write it
"ret \n\t"
/* Main "loop" */
"2: \n\t"
AESKEYGENA xmm0_xmm1 ",0x01 \n\tcall 1b \n\t"
AESKEYGENA xmm0_xmm1 ",0x02 \n\tcall 1b \n\t"
AESKEYGENA xmm0_xmm1 ",0x04 \n\tcall 1b \n\t"
AESKEYGENA xmm0_xmm1 ",0x08 \n\tcall 1b \n\t"
AESKEYGENA xmm0_xmm1 ",0x10 \n\tcall 1b \n\t"
AESKEYGENA xmm0_xmm1 ",0x20 \n\tcall 1b \n\t"
AESKEYGENA xmm0_xmm1 ",0x40 \n\tcall 1b \n\t"
AESKEYGENA xmm0_xmm1 ",0x80 \n\tcall 1b \n\t"
AESKEYGENA xmm0_xmm1 ",0x1B \n\tcall 1b \n\t"
AESKEYGENA xmm0_xmm1 ",0x36 \n\tcall 1b \n\t"
:
: "r" (rk), "r" (key)
: "memory", "cc", "0" );
}
/*
* Key expansion, 192-bit case
*/
void aesni_setkey_enc_192( unsigned char *rk,
const unsigned char *key )
{
asm( "movdqu (%1), %%xmm0 \n\t" // copy original round key
"movdqu %%xmm0, (%0) \n\t"
"add $16, %0 \n\t"
"movq 16(%1), %%xmm1 \n\t"
"movq %%xmm1, (%0) \n\t"
"add $8, %0 \n\t"
"jmp 2f \n\t" // skip auxiliary routine
/*
* Finish generating the next 6 quarter-keys.
*
* On entry xmm0 is r3:r2:r1:r0, xmm1 is stuff:stuff:r5:r4
* and xmm2 is stuff:stuff:X:stuff with X = rot( sub( r3 ) ) ^ RCON.
*
* On exit, xmm0 is r9:r8:r7:r6 and xmm1 is stuff:stuff:r11:r10
* and those are written to the round key buffer.
*/
"1: \n\t"
"pshufd $0x55, %%xmm2, %%xmm2 \n\t" // X:X:X:X
"pxor %%xmm0, %%xmm2 \n\t" // X+r3:X+r2:X+r1:r4
"pslldq $4, %%xmm0 \n\t" // etc
"pxor %%xmm0, %%xmm2 \n\t"
"pslldq $4, %%xmm0 \n\t"
"pxor %%xmm0, %%xmm2 \n\t"
"pslldq $4, %%xmm0 \n\t"
"pxor %%xmm2, %%xmm0 \n\t" // update xmm0 = r9:r8:r7:r6
"movdqu %%xmm0, (%0) \n\t"
"add $16, %0 \n\t"
"pshufd $0xff, %%xmm0, %%xmm2 \n\t" // r9:r9:r9:r9
"pxor %%xmm1, %%xmm2 \n\t" // stuff:stuff:r9+r5:r10
"pslldq $4, %%xmm1 \n\t" // r2:r1:r0:0
"pxor %%xmm2, %%xmm1 \n\t" // xmm1 = stuff:stuff:r11:r10
"movq %%xmm1, (%0) \n\t"
"add $8, %0 \n\t"
"ret \n\t"
"2: \n\t"
AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x80 \n\tcall 1b \n\t"
:
: "r" (rk), "r" (key)
: "memory", "cc", "0" );
}
/*
* Key expansion, 256-bit case
*/
void aesni_setkey_enc_256( unsigned char *rk,
const unsigned char *key )
{
asm( "movdqu (%1), %%xmm0 \n\t"
"movdqu %%xmm0, (%0) \n\t"
"add $16, %0 \n\t"
"movdqu 16(%1), %%xmm1 \n\t"
"movdqu %%xmm1, (%0) \n\t"
"jmp 2f \n\t" // skip auxiliary routine
/*
* Finish generating the next two round keys.
*
* On entry xmm0 is r3:r2:r1:r0, xmm1 is r7:r6:r5:r4 and
* xmm2 is X:stuff:stuff:stuff with X = rot( sub( r7 )) ^ RCON
*
* On exit, xmm0 is r11:r10:r9:r8 and xmm1 is r15:r14:r13:r12
* and those have been written to the output buffer.
*/
"1: \n\t"
"pshufd $0xff, %%xmm2, %%xmm2 \n\t"
"pxor %%xmm0, %%xmm2 \n\t"
"pslldq $4, %%xmm0 \n\t"
"pxor %%xmm0, %%xmm2 \n\t"
"pslldq $4, %%xmm0 \n\t"
"pxor %%xmm0, %%xmm2 \n\t"
"pslldq $4, %%xmm0 \n\t"
"pxor %%xmm2, %%xmm0 \n\t"
"add $16, %0 \n\t"
"movdqu %%xmm0, (%0) \n\t"
/* Set xmm2 to stuff:Y:stuff:stuff with Y = subword( r11 )
* and proceed to generate next round key from there */
AESKEYGENA xmm0_xmm2 ",0x00 \n\t"
"pshufd $0xaa, %%xmm2, %%xmm2 \n\t"
"pxor %%xmm1, %%xmm2 \n\t"
"pslldq $4, %%xmm1 \n\t"
"pxor %%xmm1, %%xmm2 \n\t"
"pslldq $4, %%xmm1 \n\t"
"pxor %%xmm1, %%xmm2 \n\t"
"pslldq $4, %%xmm1 \n\t"
"pxor %%xmm2, %%xmm1 \n\t"
"add $16, %0 \n\t"
"movdqu %%xmm1, (%0) \n\t"
"ret \n\t"
/*
* Main "loop" - Generating one more key than necessary,
* see definition of aes_context.buf
*/
"2: \n\t"
AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t"
AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t"
:
: "r" (rk), "r" (key)
: "memory", "cc", "0" );
}
#endif /* HAVE_AMD64 */

117
lib/aes_acc/aesni.h Normal file
View File

@ -0,0 +1,117 @@
/*
* This file is adapted from PolarSSL 1.3.19 (GPL)
*/
/**
* \file aesni.h
*
* \brief AES-NI for hardware AES acceleration on some Intel processors
*
* Copyright (C) 2013, ARM Limited, All Rights Reserved
*
* This file is part of mbed TLS (https://tls.mbed.org)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef UDP2RAW_AESNI_H_
#define UDP2RAW_AESNI_H_
#ifndef AES_ENCRYPT
#define AES_ENCRYPT 1
#endif
#ifndef AES_DECRYPT
#define AES_DECRYPT 0
#endif
#if defined(__GNUC__) && \
( defined(__amd64__) || defined(__x86_64__) ) && \
!defined(NO_AESACC)
#define HAVE_AMD64
#endif
#if defined(HAVE_AMD64)
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief AES-NI features detection routine
*
* \return 1 if CPU has support for AES-NI, 0 otherwise
*/
int aesni_supported( void );
/**
* \brief AES-NI AES-ECB block en(de)cryption
*
* \param nr number of rounds
* \param rk AES round keys
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*/
void aesni_crypt_ecb( int nr,
unsigned char *rk,
int mode,
const unsigned char input[16],
unsigned char output[16] );
/**
* \brief Compute decryption round keys from encryption round keys
*
* \param invkey Round keys for the equivalent inverse cipher
* \param fwdkey Original round keys (for encryption)
* \param nr Number of rounds (that is, number of round keys minus one)
*/
void aesni_inverse_key( unsigned char *invkey,
const unsigned char *fwdkey, int nr );
/**
* \brief Perform 128-bit key expansion (for encryption)
*
* \param rk Destination buffer where the round keys are written
* \param key Encryption key
*/
void aesni_setkey_enc_128( unsigned char *rk,
const unsigned char *key );
/**
* \brief Perform 192-bit key expansion (for encryption)
*
* \param rk Destination buffer where the round keys are written
* \param key Encryption key
*/
void aesni_setkey_enc_192( unsigned char *rk,
const unsigned char *key );
/**
* \brief Perform 256-bit key expansion (for encryption)
*
* \param rk Destination buffer where the round keys are written
* \param key Encryption key
*/
void aesni_setkey_enc_256( unsigned char *rk,
const unsigned char *key );
#ifdef __cplusplus
}
#endif
#endif /* HAVE_AMD64 */
#endif /* _AESNI_H_ */

1194
lib/aes_acc/asm/arm.S vendored Normal file

File diff suppressed because it is too large Load Diff

1178
lib/aes_acc/asm/arm64.S vendored Normal file

File diff suppressed because it is too large Load Diff

83
lib/aes_acc/asm/arm_arch.h vendored Normal file
View File

@ -0,0 +1,83 @@
/*
* Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#ifndef UDP2RAW_ARM_ARCH_H_
# define UDP2RAW_ARM_ARCH_H_
# if !defined(__ARM_ARCH__)
# if defined(__CC_ARM)
# define __ARM_ARCH__ __TARGET_ARCH_ARM
# if defined(__BIG_ENDIAN)
# define __ARMEB__
# else
# define __ARMEL__
# endif
# elif defined(__GNUC__)
# if defined(__aarch64__)
# define __ARM_ARCH__ 8
# if __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
# define __ARMEB__
# else
# define __ARMEL__
# endif
/*
* Why doesn't gcc define __ARM_ARCH__? Instead it defines
* bunch of below macros. See all_architectires[] table in
* gcc/config/arm/arm.c. On a side note it defines
* __ARMEL__/__ARMEB__ for little-/big-endian.
*/
# elif defined(__ARM_ARCH)
# define __ARM_ARCH__ __ARM_ARCH
# elif defined(__ARM_ARCH_8A__)
# define __ARM_ARCH__ 8
# elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__) || \
defined(__ARM_ARCH_7EM__)
# define __ARM_ARCH__ 7
# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
defined(__ARM_ARCH_6K__)|| defined(__ARM_ARCH_6M__) || \
defined(__ARM_ARCH_6Z__)|| defined(__ARM_ARCH_6ZK__) || \
defined(__ARM_ARCH_6T2__)
# define __ARM_ARCH__ 6
# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || \
defined(__ARM_ARCH_5E__)|| defined(__ARM_ARCH_5TE__) || \
defined(__ARM_ARCH_5TEJ__)
# define __ARM_ARCH__ 5
# elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
# define __ARM_ARCH__ 4
# else
# error "unsupported ARM architecture"
# endif
# endif
# endif
# if !defined(__ARM_MAX_ARCH__)
# define __ARM_MAX_ARCH__ __ARM_ARCH__
# endif
# if __ARM_MAX_ARCH__<__ARM_ARCH__
# error "__ARM_MAX_ARCH__ can't be less than __ARM_ARCH__"
# elif __ARM_MAX_ARCH__!=__ARM_ARCH__
# if __ARM_ARCH__<7 && __ARM_MAX_ARCH__>=7 && defined(__ARMEB__)
# error "can't build universal big-endian binary"
# endif
# endif
# if !__ASSEMBLER__
extern unsigned int OPENSSL_armcap_P;
# endif
# define ARMV7_NEON (1<<0)
# define ARMV7_TICK (1<<1)
# define ARMV8_AES (1<<2)
# define ARMV8_SHA1 (1<<3)
# define ARMV8_SHA256 (1<<4)
# define ARMV8_PMULL (1<<5)
#endif

1831
lib/aes_acc/asm/mips.S vendored Normal file

File diff suppressed because it is too large Load Diff

1831
lib/aes_acc/asm/mips_be.S vendored Normal file

File diff suppressed because it is too large Load Diff

827
lib/aes_acc/asm/x64.S vendored Normal file
View File

@ -0,0 +1,827 @@
.text
.type _vpaes_encrypt_core,@function
.align 16
_vpaes_encrypt_core:
movq %rdx,%r9
movq $16,%r11
movl 240(%rdx),%eax
movdqa %xmm9,%xmm1
movdqa .Lk_ipt(%rip),%xmm2
pandn %xmm0,%xmm1
movdqu (%r9),%xmm5
psrld $4,%xmm1
pand %xmm9,%xmm0
.byte 102,15,56,0,208
movdqa .Lk_ipt+16(%rip),%xmm0
.byte 102,15,56,0,193
pxor %xmm5,%xmm2
addq $16,%r9
pxor %xmm2,%xmm0
leaq .Lk_mc_backward(%rip),%r10
jmp .Lenc_entry
.align 16
.Lenc_loop:
movdqa %xmm13,%xmm4
movdqa %xmm12,%xmm0
.byte 102,15,56,0,226
.byte 102,15,56,0,195
pxor %xmm5,%xmm4
movdqa %xmm15,%xmm5
pxor %xmm4,%xmm0
movdqa -64(%r11,%r10,1),%xmm1
.byte 102,15,56,0,234
movdqa (%r11,%r10,1),%xmm4
movdqa %xmm14,%xmm2
.byte 102,15,56,0,211
movdqa %xmm0,%xmm3
pxor %xmm5,%xmm2
.byte 102,15,56,0,193
addq $16,%r9
pxor %xmm2,%xmm0
.byte 102,15,56,0,220
addq $16,%r11
pxor %xmm0,%xmm3
.byte 102,15,56,0,193
andq $0x30,%r11
subq $1,%rax
pxor %xmm3,%xmm0
.Lenc_entry:
movdqa %xmm9,%xmm1
movdqa %xmm11,%xmm5
pandn %xmm0,%xmm1
psrld $4,%xmm1
pand %xmm9,%xmm0
.byte 102,15,56,0,232
movdqa %xmm10,%xmm3
pxor %xmm1,%xmm0
.byte 102,15,56,0,217
movdqa %xmm10,%xmm4
pxor %xmm5,%xmm3
.byte 102,15,56,0,224
movdqa %xmm10,%xmm2
pxor %xmm5,%xmm4
.byte 102,15,56,0,211
movdqa %xmm10,%xmm3
pxor %xmm0,%xmm2
.byte 102,15,56,0,220
movdqu (%r9),%xmm5
pxor %xmm1,%xmm3
jnz .Lenc_loop
movdqa -96(%r10),%xmm4
movdqa -80(%r10),%xmm0
.byte 102,15,56,0,226
pxor %xmm5,%xmm4
.byte 102,15,56,0,195
movdqa 64(%r11,%r10,1),%xmm1
pxor %xmm4,%xmm0
.byte 102,15,56,0,193
.byte 0xf3,0xc3
.size _vpaes_encrypt_core,.-_vpaes_encrypt_core
.type _vpaes_decrypt_core,@function
.align 16
_vpaes_decrypt_core:
movq %rdx,%r9
movl 240(%rdx),%eax
movdqa %xmm9,%xmm1
movdqa .Lk_dipt(%rip),%xmm2
pandn %xmm0,%xmm1
movq %rax,%r11
psrld $4,%xmm1
movdqu (%r9),%xmm5
shlq $4,%r11
pand %xmm9,%xmm0
.byte 102,15,56,0,208
movdqa .Lk_dipt+16(%rip),%xmm0
xorq $0x30,%r11
leaq .Lk_dsbd(%rip),%r10
.byte 102,15,56,0,193
andq $0x30,%r11
pxor %xmm5,%xmm2
movdqa .Lk_mc_forward+48(%rip),%xmm5
pxor %xmm2,%xmm0
addq $16,%r9
addq %r10,%r11
jmp .Ldec_entry
.align 16
.Ldec_loop:
movdqa -32(%r10),%xmm4
movdqa -16(%r10),%xmm1
.byte 102,15,56,0,226
.byte 102,15,56,0,203
pxor %xmm4,%xmm0
movdqa 0(%r10),%xmm4
pxor %xmm1,%xmm0
movdqa 16(%r10),%xmm1
.byte 102,15,56,0,226
.byte 102,15,56,0,197
.byte 102,15,56,0,203
pxor %xmm4,%xmm0
movdqa 32(%r10),%xmm4
pxor %xmm1,%xmm0
movdqa 48(%r10),%xmm1
.byte 102,15,56,0,226
.byte 102,15,56,0,197
.byte 102,15,56,0,203
pxor %xmm4,%xmm0
movdqa 64(%r10),%xmm4
pxor %xmm1,%xmm0
movdqa 80(%r10),%xmm1
.byte 102,15,56,0,226
.byte 102,15,56,0,197
.byte 102,15,56,0,203
pxor %xmm4,%xmm0
addq $16,%r9
.byte 102,15,58,15,237,12
pxor %xmm1,%xmm0
subq $1,%rax
.Ldec_entry:
movdqa %xmm9,%xmm1
pandn %xmm0,%xmm1
movdqa %xmm11,%xmm2
psrld $4,%xmm1
pand %xmm9,%xmm0
.byte 102,15,56,0,208
movdqa %xmm10,%xmm3
pxor %xmm1,%xmm0
.byte 102,15,56,0,217
movdqa %xmm10,%xmm4
pxor %xmm2,%xmm3
.byte 102,15,56,0,224
pxor %xmm2,%xmm4
movdqa %xmm10,%xmm2
.byte 102,15,56,0,211
movdqa %xmm10,%xmm3
pxor %xmm0,%xmm2
.byte 102,15,56,0,220
movdqu (%r9),%xmm0
pxor %xmm1,%xmm3
jnz .Ldec_loop
movdqa 96(%r10),%xmm4
.byte 102,15,56,0,226
pxor %xmm0,%xmm4
movdqa 112(%r10),%xmm0
movdqa -352(%r11),%xmm2
.byte 102,15,56,0,195
pxor %xmm4,%xmm0
.byte 102,15,56,0,194
.byte 0xf3,0xc3
.size _vpaes_decrypt_core,.-_vpaes_decrypt_core
.type _vpaes_schedule_core,@function
.align 16
_vpaes_schedule_core:
call _vpaes_preheat
movdqa .Lk_rcon(%rip),%xmm8
movdqu (%rdi),%xmm0
movdqa %xmm0,%xmm3
leaq .Lk_ipt(%rip),%r11
call _vpaes_schedule_transform
movdqa %xmm0,%xmm7
leaq .Lk_sr(%rip),%r10
testq %rcx,%rcx
jnz .Lschedule_am_decrypting
movdqu %xmm0,(%rdx)
jmp .Lschedule_go
.Lschedule_am_decrypting:
movdqa (%r8,%r10,1),%xmm1
.byte 102,15,56,0,217
movdqu %xmm3,(%rdx)
xorq $0x30,%r8
.Lschedule_go:
cmpl $192,%esi
ja .Lschedule_256
je .Lschedule_192
.Lschedule_128:
movl $10,%esi
.Loop_schedule_128:
call _vpaes_schedule_round
decq %rsi
jz .Lschedule_mangle_last
call _vpaes_schedule_mangle
jmp .Loop_schedule_128
.align 16
.Lschedule_192:
movdqu 8(%rdi),%xmm0
call _vpaes_schedule_transform
movdqa %xmm0,%xmm6
pxor %xmm4,%xmm4
movhlps %xmm4,%xmm6
movl $4,%esi
.Loop_schedule_192:
call _vpaes_schedule_round
.byte 102,15,58,15,198,8
call _vpaes_schedule_mangle
call _vpaes_schedule_192_smear
call _vpaes_schedule_mangle
call _vpaes_schedule_round
decq %rsi
jz .Lschedule_mangle_last
call _vpaes_schedule_mangle
call _vpaes_schedule_192_smear
jmp .Loop_schedule_192
.align 16
.Lschedule_256:
movdqu 16(%rdi),%xmm0
call _vpaes_schedule_transform
movl $7,%esi
.Loop_schedule_256:
call _vpaes_schedule_mangle
movdqa %xmm0,%xmm6
call _vpaes_schedule_round
decq %rsi
jz .Lschedule_mangle_last
call _vpaes_schedule_mangle
pshufd $0xFF,%xmm0,%xmm0
movdqa %xmm7,%xmm5
movdqa %xmm6,%xmm7
call _vpaes_schedule_low_round
movdqa %xmm5,%xmm7
jmp .Loop_schedule_256
.align 16
.Lschedule_mangle_last:
leaq .Lk_deskew(%rip),%r11
testq %rcx,%rcx
jnz .Lschedule_mangle_last_dec
movdqa (%r8,%r10,1),%xmm1
.byte 102,15,56,0,193
leaq .Lk_opt(%rip),%r11
addq $32,%rdx
.Lschedule_mangle_last_dec:
addq $-16,%rdx
pxor .Lk_s63(%rip),%xmm0
call _vpaes_schedule_transform
movdqu %xmm0,(%rdx)
pxor %xmm0,%xmm0
pxor %xmm1,%xmm1
pxor %xmm2,%xmm2
pxor %xmm3,%xmm3
pxor %xmm4,%xmm4
pxor %xmm5,%xmm5
pxor %xmm6,%xmm6
pxor %xmm7,%xmm7
.byte 0xf3,0xc3
.size _vpaes_schedule_core,.-_vpaes_schedule_core
.type _vpaes_schedule_192_smear,@function
.align 16
_vpaes_schedule_192_smear:
pshufd $0x80,%xmm6,%xmm1
pshufd $0xFE,%xmm7,%xmm0
pxor %xmm1,%xmm6
pxor %xmm1,%xmm1
pxor %xmm0,%xmm6
movdqa %xmm6,%xmm0
movhlps %xmm1,%xmm6
.byte 0xf3,0xc3
.size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear
.type _vpaes_schedule_round,@function
.align 16
_vpaes_schedule_round:
pxor %xmm1,%xmm1
.byte 102,65,15,58,15,200,15
.byte 102,69,15,58,15,192,15
pxor %xmm1,%xmm7
pshufd $0xFF,%xmm0,%xmm0
.byte 102,15,58,15,192,1
_vpaes_schedule_low_round:
movdqa %xmm7,%xmm1
pslldq $4,%xmm7
pxor %xmm1,%xmm7
movdqa %xmm7,%xmm1
pslldq $8,%xmm7
pxor %xmm1,%xmm7
pxor .Lk_s63(%rip),%xmm7
movdqa %xmm9,%xmm1
pandn %xmm0,%xmm1
psrld $4,%xmm1
pand %xmm9,%xmm0
movdqa %xmm11,%xmm2
.byte 102,15,56,0,208
pxor %xmm1,%xmm0
movdqa %xmm10,%xmm3
.byte 102,15,56,0,217
pxor %xmm2,%xmm3
movdqa %xmm10,%xmm4
.byte 102,15,56,0,224
pxor %xmm2,%xmm4
movdqa %xmm10,%xmm2
.byte 102,15,56,0,211
pxor %xmm0,%xmm2
movdqa %xmm10,%xmm3
.byte 102,15,56,0,220
pxor %xmm1,%xmm3
movdqa %xmm13,%xmm4
.byte 102,15,56,0,226
movdqa %xmm12,%xmm0
.byte 102,15,56,0,195
pxor %xmm4,%xmm0
pxor %xmm7,%xmm0
movdqa %xmm0,%xmm7
.byte 0xf3,0xc3
.size _vpaes_schedule_round,.-_vpaes_schedule_round
.type _vpaes_schedule_transform,@function
.align 16
_vpaes_schedule_transform:
movdqa %xmm9,%xmm1
pandn %xmm0,%xmm1
psrld $4,%xmm1
pand %xmm9,%xmm0
movdqa (%r11),%xmm2
.byte 102,15,56,0,208
movdqa 16(%r11),%xmm0
.byte 102,15,56,0,193
pxor %xmm2,%xmm0
.byte 0xf3,0xc3
.size _vpaes_schedule_transform,.-_vpaes_schedule_transform
.type _vpaes_schedule_mangle,@function
.align 16
_vpaes_schedule_mangle:
movdqa %xmm0,%xmm4
movdqa .Lk_mc_forward(%rip),%xmm5
testq %rcx,%rcx
jnz .Lschedule_mangle_dec
addq $16,%rdx
pxor .Lk_s63(%rip),%xmm4
.byte 102,15,56,0,229
movdqa %xmm4,%xmm3
.byte 102,15,56,0,229
pxor %xmm4,%xmm3
.byte 102,15,56,0,229
pxor %xmm4,%xmm3
jmp .Lschedule_mangle_both
.align 16
.Lschedule_mangle_dec:
leaq .Lk_dksd(%rip),%r11
movdqa %xmm9,%xmm1
pandn %xmm4,%xmm1
psrld $4,%xmm1
pand %xmm9,%xmm4
movdqa 0(%r11),%xmm2
.byte 102,15,56,0,212
movdqa 16(%r11),%xmm3
.byte 102,15,56,0,217
pxor %xmm2,%xmm3
.byte 102,15,56,0,221
movdqa 32(%r11),%xmm2
.byte 102,15,56,0,212
pxor %xmm3,%xmm2
movdqa 48(%r11),%xmm3
.byte 102,15,56,0,217
pxor %xmm2,%xmm3
.byte 102,15,56,0,221
movdqa 64(%r11),%xmm2
.byte 102,15,56,0,212
pxor %xmm3,%xmm2
movdqa 80(%r11),%xmm3
.byte 102,15,56,0,217
pxor %xmm2,%xmm3
.byte 102,15,56,0,221
movdqa 96(%r11),%xmm2
.byte 102,15,56,0,212
pxor %xmm3,%xmm2
movdqa 112(%r11),%xmm3
.byte 102,15,56,0,217
pxor %xmm2,%xmm3
addq $-16,%rdx
.Lschedule_mangle_both:
movdqa (%r8,%r10,1),%xmm1
.byte 102,15,56,0,217
addq $-16,%r8
andq $0x30,%r8
movdqu %xmm3,(%rdx)
.byte 0xf3,0xc3
.size _vpaes_schedule_mangle,.-_vpaes_schedule_mangle
.globl vpaes_set_encrypt_key
.type vpaes_set_encrypt_key,@function
.align 16
vpaes_set_encrypt_key:
movl %esi,%eax
shrl $5,%eax
addl $5,%eax
movl %eax,240(%rdx)
movl $0,%ecx
movl $0x30,%r8d
call _vpaes_schedule_core
xorl %eax,%eax
.byte 0xf3,0xc3
.size vpaes_set_encrypt_key,.-vpaes_set_encrypt_key
.globl vpaes_set_decrypt_key
.type vpaes_set_decrypt_key,@function
.align 16
vpaes_set_decrypt_key:
movl %esi,%eax
shrl $5,%eax
addl $5,%eax
movl %eax,240(%rdx)
shll $4,%eax
leaq 16(%rdx,%rax,1),%rdx
movl $1,%ecx
movl %esi,%r8d
shrl $1,%r8d
andl $32,%r8d
xorl $32,%r8d
call _vpaes_schedule_core
xorl %eax,%eax
.byte 0xf3,0xc3
.size vpaes_set_decrypt_key,.-vpaes_set_decrypt_key
.globl vpaes_encrypt
.type vpaes_encrypt,@function
.align 16
vpaes_encrypt:
movdqu (%rdi),%xmm0
call _vpaes_preheat
call _vpaes_encrypt_core
movdqu %xmm0,(%rsi)
.byte 0xf3,0xc3
.size vpaes_encrypt,.-vpaes_encrypt
.globl vpaes_decrypt
.type vpaes_decrypt,@function
.align 16
vpaes_decrypt:
movdqu (%rdi),%xmm0
call _vpaes_preheat
call _vpaes_decrypt_core
movdqu %xmm0,(%rsi)
.byte 0xf3,0xc3
.size vpaes_decrypt,.-vpaes_decrypt
.globl vpaes_cbc_encrypt
.type vpaes_cbc_encrypt,@function
.align 16
vpaes_cbc_encrypt:
xchgq %rcx,%rdx
subq $16,%rcx
jc .Lcbc_abort
movdqu (%r8),%xmm6
subq %rdi,%rsi
call _vpaes_preheat
cmpl $0,%r9d
je .Lcbc_dec_loop
jmp .Lcbc_enc_loop
.align 16
.Lcbc_enc_loop:
movdqu (%rdi),%xmm0
pxor %xmm6,%xmm0
call _vpaes_encrypt_core
movdqa %xmm0,%xmm6
movdqu %xmm0,(%rsi,%rdi,1)
leaq 16(%rdi),%rdi
subq $16,%rcx
jnc .Lcbc_enc_loop
jmp .Lcbc_done
.align 16
.Lcbc_dec_loop:
movdqu (%rdi),%xmm0
movdqa %xmm0,%xmm7
call _vpaes_decrypt_core
pxor %xmm6,%xmm0
movdqa %xmm7,%xmm6
movdqu %xmm0,(%rsi,%rdi,1)
leaq 16(%rdi),%rdi
subq $16,%rcx
jnc .Lcbc_dec_loop
.Lcbc_done:
movdqu %xmm6,(%r8)
.Lcbc_abort:
.byte 0xf3,0xc3
.size vpaes_cbc_encrypt,.-vpaes_cbc_encrypt
.type _vpaes_preheat,@function
.align 16
_vpaes_preheat:
leaq .Lk_s0F(%rip),%r10
movdqa -32(%r10),%xmm10
movdqa -16(%r10),%xmm11
movdqa 0(%r10),%xmm9
movdqa 48(%r10),%xmm13
movdqa 64(%r10),%xmm12
movdqa 80(%r10),%xmm15
movdqa 96(%r10),%xmm14
.byte 0xf3,0xc3
.size _vpaes_preheat,.-_vpaes_preheat
.type _vpaes_consts,@object
.align 64
_vpaes_consts:
.Lk_inv:
.quad 0x0E05060F0D080180, 0x040703090A0B0C02
.quad 0x01040A060F0B0780, 0x030D0E0C02050809
.Lk_s0F:
.quad 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F
.Lk_ipt:
.quad 0xC2B2E8985A2A7000, 0xCABAE09052227808
.quad 0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81
.Lk_sb1:
.quad 0xB19BE18FCB503E00, 0xA5DF7A6E142AF544
.quad 0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF
.Lk_sb2:
.quad 0xE27A93C60B712400, 0x5EB7E955BC982FCD
.quad 0x69EB88400AE12900, 0xC2A163C8AB82234A
.Lk_sbo:
.quad 0xD0D26D176FBDC700, 0x15AABF7AC502A878
.quad 0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA
.Lk_mc_forward:
.quad 0x0407060500030201, 0x0C0F0E0D080B0A09
.quad 0x080B0A0904070605, 0x000302010C0F0E0D
.quad 0x0C0F0E0D080B0A09, 0x0407060500030201
.quad 0x000302010C0F0E0D, 0x080B0A0904070605
.Lk_mc_backward:
.quad 0x0605040702010003, 0x0E0D0C0F0A09080B
.quad 0x020100030E0D0C0F, 0x0A09080B06050407
.quad 0x0E0D0C0F0A09080B, 0x0605040702010003
.quad 0x0A09080B06050407, 0x020100030E0D0C0F
.Lk_sr:
.quad 0x0706050403020100, 0x0F0E0D0C0B0A0908
.quad 0x030E09040F0A0500, 0x0B06010C07020D08
.quad 0x0F060D040B020900, 0x070E050C030A0108
.quad 0x0B0E0104070A0D00, 0x0306090C0F020508
.Lk_rcon:
.quad 0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81
.Lk_s63:
.quad 0x5B5B5B5B5B5B5B5B, 0x5B5B5B5B5B5B5B5B
.Lk_opt:
.quad 0xFF9F4929D6B66000, 0xF7974121DEBE6808
.quad 0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0
.Lk_deskew:
.quad 0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A
.quad 0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77
.Lk_dksd:
.quad 0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9
.quad 0x41C277F4B5368300, 0x5FDC69EAAB289D1E
.Lk_dksb:
.quad 0x9A4FCA1F8550D500, 0x03D653861CC94C99
.quad 0x115BEDA7B6FC4A00, 0xD993256F7E3482C8
.Lk_dkse:
.quad 0xD5031CCA1FC9D600, 0x53859A4C994F5086
.quad 0xA23196054FDC7BE8, 0xCD5EF96A20B31487
.Lk_dks9:
.quad 0xB6116FC87ED9A700, 0x4AED933482255BFC
.quad 0x4576516227143300, 0x8BB89FACE9DAFDCE
.Lk_dipt:
.quad 0x0F505B040B545F00, 0x154A411E114E451A
.quad 0x86E383E660056500, 0x12771772F491F194
.Lk_dsb9:
.quad 0x851C03539A86D600, 0xCAD51F504F994CC9
.quad 0xC03B1789ECD74900, 0x725E2C9EB2FBA565
.Lk_dsbd:
.quad 0x7D57CCDFE6B1A200, 0xF56E9B13882A4439
.quad 0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3
.Lk_dsbb:
.quad 0xD022649296B44200, 0x602646F6B0F2D404
.quad 0xC19498A6CD596700, 0xF3FF0C3E3255AA6B
.Lk_dsbe:
.quad 0x46F2929626D4D000, 0x2242600464B4F6B0
.quad 0x0C55A6CDFFAAC100, 0x9467F36B98593E32
.Lk_dsbo:
.quad 0x1387EA537EF94000, 0xC7AA6DB9D4943E2D
.quad 0x12D7560F93441D00, 0xCA4B8159D8C58E9C
.byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,120,56,54,95,54,52,47,83,83,83,69,51,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0
.align 64
.size _vpaes_consts,.-_vpaes_consts

3244
lib/aes_acc/asm/x86.S vendored Normal file

File diff suppressed because it is too large Load Diff

1459
lib/aes_faster_c/aes.cpp Normal file

File diff suppressed because it is too large Load Diff

268
lib/aes_faster_c/aes.h Normal file
View File

@ -0,0 +1,268 @@
/**
* \file aes.h
*
* \brief AES block cipher
*
* Copyright (C) 2006-2014, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_AES_H
#define POLARSSL_AES_H
/*
#if !defined(POLARSSL_CONFIG_FILE)
#include "config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif
*/
////////modification begin
#define POLARSSL_AES_ROM_TABLES
#define POLARSSL_CIPHER_MODE_CBC
#define POLARSSL_CIPHER_MODE_CFB
//#define POLARSSL_SELF_TEST
#define polarssl_printf printf
///////add end
#include <string.h>
#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
#include <basetsd.h>
typedef UINT32 uint32_t;
#else
#include <inttypes.h>
#endif
/* padlock.c and aesni.c rely on these values! */
#define AES_ENCRYPT 1
#define AES_DECRYPT 0
#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
#if !defined(POLARSSL_AES_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief AES context structure
*
* \note buf is able to hold 32 extra bytes, which can be used:
* - for alignment purposes if VIA padlock is used, and/or
* - to simplify key expansion in the 256-bit case by
* generating an extra round key
*/
typedef struct
{
int nr; /*!< number of rounds */
uint32_t *rk; /*!< AES round keys */
uint32_t buf[68]; /*!< unaligned data */
}
aes_context;
/**
* \brief Initialize AES context
*
* \param ctx AES context to be initialized
*/
void aes_init( aes_context *ctx );
/**
* \brief Clear AES context
*
* \param ctx AES context to be cleared
*/
void aes_free( aes_context *ctx );
/**
* \brief AES key schedule (encryption)
*
* \param ctx AES context to be initialized
* \param key encryption key
* \param keysize must be 128, 192 or 256
*
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
*/
int aes_setkey_enc( aes_context *ctx, const unsigned char *key,
unsigned int keysize );
/**
* \brief AES key schedule (decryption)
*
* \param ctx AES context to be initialized
* \param key decryption key
* \param keysize must be 128, 192 or 256
*
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
*/
int aes_setkey_dec( aes_context *ctx, const unsigned char *key,
unsigned int keysize );
/**
* \brief AES-ECB block encryption/decryption
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return 0 if successful
*/
int aes_crypt_ecb( aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
#if defined(POLARSSL_CIPHER_MODE_CBC)
/**
* \brief AES-CBC buffer encryption/decryption
* Length should be a multiple of the block
* size (16 bytes)
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH
*/
int aes_crypt_cbc( aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#endif /* POLARSSL_CIPHER_MODE_CBC */
#if defined(POLARSSL_CIPHER_MODE_CFB)
/**
* \brief AES-CFB128 buffer encryption/decryption.
*
* Note: Due to the nature of CFB you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param length length of the input data
* \param iv_off offset in IV (updated after use)
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful
*/
int aes_crypt_cfb128( aes_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
/**
* \brief AES-CFB8 buffer encryption/decryption.
*
* Note: Due to the nature of CFB you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful
*/
int aes_crypt_cfb8( aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#endif /*POLARSSL_CIPHER_MODE_CFB */
#if defined(POLARSSL_CIPHER_MODE_CTR)
/**
* \brief AES-CTR buffer encryption/decryption
*
* Warning: You have to keep the maximum use of your counter in mind!
*
* Note: Due to the nature of CTR you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
*
* \param ctx AES context
* \param length The length of the data
* \param nc_off The offset in the current stream_block (for resuming
* within current cipher stream). The offset pointer to
* should be 0 at the start of a stream.
* \param nonce_counter The 128-bit nonce and counter.
* \param stream_block The saved stream-block for resuming. Is overwritten
* by the function.
* \param input The input data stream
* \param output The output data stream
*
* \return 0 if successful
*/
int aes_crypt_ctr( aes_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[16],
unsigned char stream_block[16],
const unsigned char *input,
unsigned char *output );
#endif /* POLARSSL_CIPHER_MODE_CTR */
#ifdef __cplusplus
}
#endif
#else /* POLARSSL_AES_ALT */
#include "aes_alt.h"
#endif /* POLARSSL_AES_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int aes_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* aes.h */

View File

@ -0,0 +1,103 @@
#include "aes.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#if defined(AES256) && (AES256 == 1)
#define AES_KEYSIZE 256
#elif defined(AES192) && (AES192 == 1)
#define AES_KEYSIZE 192
#else
#define AES_KEYSIZE 128
#endif
void AES_ECB_encrypt_buffer(const uint8_t* input, const uint8_t* key, uint8_t *output)
{
static aes_context ctx;
if(key!=0)
{
aes_init( &ctx);
aes_setkey_enc(&ctx,key,AES_KEYSIZE);
}
int ret=aes_crypt_ecb( &ctx, AES_ENCRYPT, (const unsigned char*)input,(unsigned char*) output );
assert(ret==0);
return ;
}
void AES_ECB_decrypt_buffer(const uint8_t* input, const uint8_t* key, uint8_t *output)
{
static aes_context ctx;
if(key!=0)
{
aes_init( &ctx);
aes_setkey_dec(&ctx,key,AES_KEYSIZE);
}
int ret=aes_crypt_ecb( &ctx, AES_DECRYPT, (const unsigned char*)input,(unsigned char*) output );
assert(ret==0);
return ;
}
void AES_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
{
static aes_context ctx;
char tmp_iv[16];
if(key!=0)
{
aes_init( &ctx);
aes_setkey_enc(&ctx,key,AES_KEYSIZE);
}
memcpy(tmp_iv,iv,16);
int ret=aes_crypt_cbc( &ctx, AES_ENCRYPT, length, (unsigned char* )tmp_iv, (const unsigned char*)input,(unsigned char*) output );
assert(ret==0);
return ;
}
void AES_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
{
static aes_context ctx;
char tmp_iv[16];
if(key!=0)
{
aes_init( &ctx);
aes_setkey_dec(&ctx,key,AES_KEYSIZE);
}
memcpy(tmp_iv,iv,16);
int ret=aes_crypt_cbc( &ctx,AES_DECRYPT, length, (unsigned char*)tmp_iv, (const unsigned char*)input, (unsigned char*) output );
assert(ret==0);
}
void AES_CFB_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
{
static aes_context ctx;
char tmp_iv[16];
if(key!=0)
{
aes_init( &ctx);
aes_setkey_enc(&ctx,key,AES_KEYSIZE);
}
memcpy(tmp_iv,iv,16);
size_t offset=0;
int ret=aes_crypt_cfb128( &ctx, AES_ENCRYPT, length,&offset, (unsigned char* )tmp_iv, (const unsigned char*)input,(unsigned char*) output );
assert(ret==0);
return ;
}
void AES_CFB_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
{
static aes_context ctx;
char tmp_iv[16];
if(key!=0)
{
aes_init( &ctx);
aes_setkey_enc(&ctx,key,AES_KEYSIZE);// its aes_setkey_enc again, no typo
}
memcpy(tmp_iv,iv,16);
size_t offset=0;
int ret=aes_crypt_cfb128( &ctx,AES_DECRYPT, length,&offset, (unsigned char*)tmp_iv, (const unsigned char*)input, (unsigned char*) output );
assert(ret==0);
return;
}

176
lib/md5.c
View File

@ -1,176 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
/*
* this file comes from https://github.com/pod32g/MD5/blob/master/md5.c
*/
// Constants are the integer part of the sines of integers (in radians) * 2^32.
const uint32_t k[64] = {
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee ,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501 ,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be ,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 ,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa ,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8 ,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed ,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a ,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c ,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70 ,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05 ,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 ,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039 ,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1 ,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1 ,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };
// r specifies the per-round shift amounts
const uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
// leftrotate function definition
#define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
void to_bytes(uint32_t val, uint8_t *bytes)
{
bytes[0] = (uint8_t) val;
bytes[1] = (uint8_t) (val >> 8);
bytes[2] = (uint8_t) (val >> 16);
bytes[3] = (uint8_t) (val >> 24);
}
uint32_t to_int32(const uint8_t *bytes)
{
return (uint32_t) bytes[0]
| ((uint32_t) bytes[1] << 8)
| ((uint32_t) bytes[2] << 16)
| ((uint32_t) bytes[3] << 24);
}
void md5(const uint8_t *initial_msg, size_t initial_len, uint8_t *digest) {
// These vars will contain the hash
uint32_t h0, h1, h2, h3;
// Message (to prepare)
uint8_t *msg = NULL;
size_t new_len, offset;
uint32_t w[16];
uint32_t a, b, c, d, i, f, g, temp;
// Initialize variables - simple count in nibbles:
h0 = 0x67452301;
h1 = 0xefcdab89;
h2 = 0x98badcfe;
h3 = 0x10325476;
//Pre-processing:
//append "1" bit to message
//append "0" bits until message length in bits ≡ 448 (mod 512)
//append length mod (2^64) to message
for (new_len = initial_len + 1; new_len % (512/8) != 448/8; new_len++)
;
uint8_t buf[new_len + 8];
msg = buf;//(uint8_t*)malloc(new_len + 8);
memcpy(msg, initial_msg, initial_len);
msg[initial_len] = 0x80; // append the "1" bit; most significant bit is "first"
for (offset = initial_len + 1; offset < new_len; offset++)
msg[offset] = 0; // append "0" bits
// append the len in bits at the end of the buffer.
to_bytes(initial_len*8, msg + new_len);
// initial_len>>29 == initial_len*8>>32, but avoids overflow.
to_bytes(initial_len>>29, msg + new_len + 4);
// Process the message in successive 512-bit chunks:
//for each 512-bit chunk of message:
for(offset=0; offset<new_len; offset += (512/8)) {
// break chunk into sixteen 32-bit words w[j], 0 ≤ j ≤ 15
for (i = 0; i < 16; i++)
w[i] = to_int32(msg + offset + i*4);
// Initialize hash value for this chunk:
a = h0;
b = h1;
c = h2;
d = h3;
// Main loop:
for(i = 0; i<64; i++) {
if (i < 16) {
f = (b & c) | ((~b) & d);
g = i;
} else if (i < 32) {
f = (d & b) | ((~d) & c);
g = (5*i + 1) % 16;
} else if (i < 48) {
f = b ^ c ^ d;
g = (3*i + 5) % 16;
} else {
f = c ^ (b | (~d));
g = (7*i) % 16;
}
temp = d;
d = c;
c = b;
b = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]);
a = temp;
}
// Add this chunk's hash to result so far:
h0 += a;
h1 += b;
h2 += c;
h3 += d;
}
// cleanup
//free(msg);
//var char digest[16] := h0 append h1 append h2 append h3 //(Output is in little-endian)
to_bytes(h0, digest);
to_bytes(h1, digest + 4);
to_bytes(h2, digest + 8);
to_bytes(h3, digest + 12);
}
/*
int main(int argc, char **argv) {
char *msg;
size_t len;
int i;
uint8_t result[16];
if (argc < 2) {
printf("usage: %s 'string'\n", argv[0]);
return 1;
}
msg = argv[1];
len = strlen(msg);
// benchmark
for (i = 0; i < 1000000; i++) {
md5((uint8_t*)msg, len, result);
}
// display result
for (i = 0; i < 16; i++)
printf("%2.2x", result[i]);
puts("");
return 0;
}
*/

403
lib/md5.cpp Executable file
View File

@ -0,0 +1,403 @@
/*
* This file is adapted from PolarSSL 1.3.19 (GPL)
*/
/*
* RFC 1321 compliant MD5 implementation
*
* Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
*
* This file is part of mbed TLS (https://tls.mbed.org)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* The MD5 algorithm was designed by Ron Rivest in 1991.
*
* http://www.ietf.org/rfc/rfc1321.txt
*/
#include <string.h>
#include <stddef.h>
#include <stdint.h>
typedef struct
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[4]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
unsigned char ipad[64]; /*!< HMAC: inner padding */
unsigned char opad[64]; /*!< HMAC: outer padding */
}
md5_context;
/* Implementation that should never be optimized out by the compiler */
static void polarssl_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char *) v; while( n-- ) *p++ = 0;
}
/*
* 32-bit integer manipulation macros (little endian)
*/
#ifndef GET_UINT32_LE
#define GET_UINT32_LE(n,b,i) \
{ \
(n) = ( (uint32_t) (b)[(i) ] ) \
| ( (uint32_t) (b)[(i) + 1] << 8 ) \
| ( (uint32_t) (b)[(i) + 2] << 16 ) \
| ( (uint32_t) (b)[(i) + 3] << 24 ); \
}
#endif
#ifndef PUT_UINT32_LE
#define PUT_UINT32_LE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
(b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
(b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
(b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
}
#endif
void md5_init( md5_context *ctx )
{
memset( ctx, 0, sizeof( md5_context ) );
}
void md5_free( md5_context *ctx )
{
if( ctx == NULL )
return;
polarssl_zeroize( ctx, sizeof( md5_context ) );
}
/*
* MD5 context setup
*/
void md5_starts( md5_context *ctx )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476;
}
void md5_process( md5_context *ctx, const unsigned char data[64] )
{
uint32_t X[16], A, B, C, D;
GET_UINT32_LE( X[ 0], data, 0 );
GET_UINT32_LE( X[ 1], data, 4 );
GET_UINT32_LE( X[ 2], data, 8 );
GET_UINT32_LE( X[ 3], data, 12 );
GET_UINT32_LE( X[ 4], data, 16 );
GET_UINT32_LE( X[ 5], data, 20 );
GET_UINT32_LE( X[ 6], data, 24 );
GET_UINT32_LE( X[ 7], data, 28 );
GET_UINT32_LE( X[ 8], data, 32 );
GET_UINT32_LE( X[ 9], data, 36 );
GET_UINT32_LE( X[10], data, 40 );
GET_UINT32_LE( X[11], data, 44 );
GET_UINT32_LE( X[12], data, 48 );
GET_UINT32_LE( X[13], data, 52 );
GET_UINT32_LE( X[14], data, 56 );
GET_UINT32_LE( X[15], data, 60 );
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define P(a,b,c,d,k,s,t) \
{ \
a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
}
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
#define F(x,y,z) (z ^ (x & (y ^ z)))
P( A, B, C, D, 0, 7, 0xD76AA478 );
P( D, A, B, C, 1, 12, 0xE8C7B756 );
P( C, D, A, B, 2, 17, 0x242070DB );
P( B, C, D, A, 3, 22, 0xC1BDCEEE );
P( A, B, C, D, 4, 7, 0xF57C0FAF );
P( D, A, B, C, 5, 12, 0x4787C62A );
P( C, D, A, B, 6, 17, 0xA8304613 );
P( B, C, D, A, 7, 22, 0xFD469501 );
P( A, B, C, D, 8, 7, 0x698098D8 );
P( D, A, B, C, 9, 12, 0x8B44F7AF );
P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
P( B, C, D, A, 11, 22, 0x895CD7BE );
P( A, B, C, D, 12, 7, 0x6B901122 );
P( D, A, B, C, 13, 12, 0xFD987193 );
P( C, D, A, B, 14, 17, 0xA679438E );
P( B, C, D, A, 15, 22, 0x49B40821 );
#undef F
#define F(x,y,z) (y ^ (z & (x ^ y)))
P( A, B, C, D, 1, 5, 0xF61E2562 );
P( D, A, B, C, 6, 9, 0xC040B340 );
P( C, D, A, B, 11, 14, 0x265E5A51 );
P( B, C, D, A, 0, 20, 0xE9B6C7AA );
P( A, B, C, D, 5, 5, 0xD62F105D );
P( D, A, B, C, 10, 9, 0x02441453 );
P( C, D, A, B, 15, 14, 0xD8A1E681 );
P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
P( A, B, C, D, 9, 5, 0x21E1CDE6 );
P( D, A, B, C, 14, 9, 0xC33707D6 );
P( C, D, A, B, 3, 14, 0xF4D50D87 );
P( B, C, D, A, 8, 20, 0x455A14ED );
P( A, B, C, D, 13, 5, 0xA9E3E905 );
P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
P( C, D, A, B, 7, 14, 0x676F02D9 );
P( B, C, D, A, 12, 20, 0x8D2A4C8A );
#undef F
#define F(x,y,z) (x ^ y ^ z)
P( A, B, C, D, 5, 4, 0xFFFA3942 );
P( D, A, B, C, 8, 11, 0x8771F681 );
P( C, D, A, B, 11, 16, 0x6D9D6122 );
P( B, C, D, A, 14, 23, 0xFDE5380C );
P( A, B, C, D, 1, 4, 0xA4BEEA44 );
P( D, A, B, C, 4, 11, 0x4BDECFA9 );
P( C, D, A, B, 7, 16, 0xF6BB4B60 );
P( B, C, D, A, 10, 23, 0xBEBFBC70 );
P( A, B, C, D, 13, 4, 0x289B7EC6 );
P( D, A, B, C, 0, 11, 0xEAA127FA );
P( C, D, A, B, 3, 16, 0xD4EF3085 );
P( B, C, D, A, 6, 23, 0x04881D05 );
P( A, B, C, D, 9, 4, 0xD9D4D039 );
P( D, A, B, C, 12, 11, 0xE6DB99E5 );
P( C, D, A, B, 15, 16, 0x1FA27CF8 );
P( B, C, D, A, 2, 23, 0xC4AC5665 );
#undef F
#define F(x,y,z) (y ^ (x | ~z))
P( A, B, C, D, 0, 6, 0xF4292244 );
P( D, A, B, C, 7, 10, 0x432AFF97 );
P( C, D, A, B, 14, 15, 0xAB9423A7 );
P( B, C, D, A, 5, 21, 0xFC93A039 );
P( A, B, C, D, 12, 6, 0x655B59C3 );
P( D, A, B, C, 3, 10, 0x8F0CCC92 );
P( C, D, A, B, 10, 15, 0xFFEFF47D );
P( B, C, D, A, 1, 21, 0x85845DD1 );
P( A, B, C, D, 8, 6, 0x6FA87E4F );
P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
P( C, D, A, B, 6, 15, 0xA3014314 );
P( B, C, D, A, 13, 21, 0x4E0811A1 );
P( A, B, C, D, 4, 6, 0xF7537E82 );
P( D, A, B, C, 11, 10, 0xBD3AF235 );
P( C, D, A, B, 2, 15, 0x2AD7D2BB );
P( B, C, D, A, 9, 21, 0xEB86D391 );
#undef F
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
}
/*
* MD5 process buffer
*/
void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen )
{
size_t fill;
uint32_t left;
if( ilen == 0 )
return;
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += (uint32_t) ilen;
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < (uint32_t) ilen )
ctx->total[1]++;
if( left && ilen >= fill )
{
memcpy( (void *) (ctx->buffer + left), input, fill );
md5_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
}
while( ilen >= 64 )
{
md5_process( ctx, input );
input += 64;
ilen -= 64;
}
if( ilen > 0 )
{
memcpy( (void *) (ctx->buffer + left), input, ilen );
}
}
static const unsigned char md5_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* MD5 final digest
*/
void md5_finish( md5_context *ctx, unsigned char output[16] )
{
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT32_LE( low, msglen, 0 );
PUT_UINT32_LE( high, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
md5_update( ctx, md5_padding, padn );
md5_update( ctx, msglen, 8 );
PUT_UINT32_LE( ctx->state[0], output, 0 );
PUT_UINT32_LE( ctx->state[1], output, 4 );
PUT_UINT32_LE( ctx->state[2], output, 8 );
PUT_UINT32_LE( ctx->state[3], output, 12 );
}
/*
* output = MD5( input buffer )
*/
void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
{
/*static md5_context ctx;
static int done=0;
if(done==0)
{
md5_init( &ctx );
done=1;
}*/
md5_context ctx;
md5_init( &ctx );
md5_starts( &ctx );
md5_update( &ctx, input, ilen );
md5_finish( &ctx, output );
md5_free( &ctx );
}
/*
* MD5 HMAC context setup
*/
void md5_hmac_starts( md5_context *ctx, const unsigned char *key,
size_t keylen )
{
size_t i;
unsigned char sum[16];
if( keylen > 64 )
{
md5( key, keylen, sum );
keylen = 16;
key = sum;
}
memset( ctx->ipad, 0x36, 64 );
memset( ctx->opad, 0x5C, 64 );
for( i = 0; i < keylen; i++ )
{
ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
}
md5_starts( ctx );
md5_update( ctx, ctx->ipad, 64 );
polarssl_zeroize( sum, sizeof( sum ) );
}
/*
* MD5 HMAC process buffer
*/
void md5_hmac_update( md5_context *ctx, const unsigned char *input,
size_t ilen )
{
md5_update( ctx, input, ilen );
}
/*
* MD5 HMAC final digest
*/
void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
{
unsigned char tmpbuf[16];
md5_finish( ctx, tmpbuf );
md5_starts( ctx );
md5_update( ctx, ctx->opad, 64 );
md5_update( ctx, tmpbuf, 16 );
md5_finish( ctx, output );
polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
}
/*
* MD5 HMAC context reset
*/
void md5_hmac_reset( md5_context *ctx )
{
md5_starts( ctx );
md5_update( ctx, ctx->ipad, 64 );
}
/*
* output = HMAC-MD5( hmac key, input buffer )
*/
void md5_hmac( const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char output[16] )
{
md5_context ctx;
md5_init( &ctx );
md5_hmac_starts( &ctx, key, keylen );
md5_hmac_update( &ctx, input, ilen );
md5_hmac_finish( &ctx, output );
md5_free( &ctx );
}

View File

@ -1,9 +1,7 @@
#ifndef _MD5_H_
#define _MD5_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef UDP2RAW_MD5_H_
#define UDP2RAW_MD5_H_
#include <stdint.h>
#include <stddef.h>
void md5(const uint8_t *initial_msg, size_t initial_len, uint8_t *digest);

865
lib/pbkdf2-sha1.cpp Normal file
View File

@ -0,0 +1,865 @@
/*
this file is from https://github.com/kholia/PKCS5_PBKDF2
*
* FIPS-180-1 compliant SHA-1 implementation
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* The SHA-1 standard was published by NIST in 1993.
*
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
*
* Copyright 2012 Mathias Olsson mathias@kompetensum.com
*
* This file is dual licensed as either GPL version 2 or Apache License 2.0 at your choice
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* http://www.apache.org/licenses/
*
* Note that PolarSSL uses GPL with a FOSS License Exception */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(TEST) ||defined(DEBUG)
#undef TEST
#undef DEBUG
#warning "undefined TEST/DEBUG"
#endif
typedef struct {
unsigned long total[2]; /*!< number of bytes processed */
unsigned long state[5]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
unsigned char ipad[64]; /*!< HMAC: inner padding */
unsigned char opad[64]; /*!< HMAC: outer padding */
} sha1_context;
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_ULONG_BE
#define GET_ULONG_BE(n,b,i) \
{ \
(n) = ( (unsigned long) (b)[(i) ] << 24 ) \
| ( (unsigned long) (b)[(i) + 1] << 16 ) \
| ( (unsigned long) (b)[(i) + 2] << 8 ) \
| ( (unsigned long) (b)[(i) + 3] ); \
}
#endif
#ifndef PUT_ULONG_BE
#define PUT_ULONG_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
}
#endif
/*
* SHA-1 context setup
*/
void sha1_starts(sha1_context * ctx)
{
ctx->total[0] = 0;
ctx->total[1] = 0;
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476;
ctx->state[4] = 0xC3D2E1F0;
}
static void sha1_process(sha1_context * ctx, const unsigned char data[64])
{
unsigned long temp, W[16], A, B, C, D, E;
GET_ULONG_BE(W[0], data, 0);
GET_ULONG_BE(W[1], data, 4);
GET_ULONG_BE(W[2], data, 8);
GET_ULONG_BE(W[3], data, 12);
GET_ULONG_BE(W[4], data, 16);
GET_ULONG_BE(W[5], data, 20);
GET_ULONG_BE(W[6], data, 24);
GET_ULONG_BE(W[7], data, 28);
GET_ULONG_BE(W[8], data, 32);
GET_ULONG_BE(W[9], data, 36);
GET_ULONG_BE(W[10], data, 40);
GET_ULONG_BE(W[11], data, 44);
GET_ULONG_BE(W[12], data, 48);
GET_ULONG_BE(W[13], data, 52);
GET_ULONG_BE(W[14], data, 56);
GET_ULONG_BE(W[15], data, 60);
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define R(t) \
( \
temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
( W[t & 0x0F] = S(temp,1) ) \
)
#define P(a,b,c,d,e,x) \
{ \
e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
}
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
E = ctx->state[4];
#define F(x,y,z) (z ^ (x & (y ^ z)))
#define K 0x5A827999
P(A, B, C, D, E, W[0]);
P(E, A, B, C, D, W[1]);
P(D, E, A, B, C, W[2]);
P(C, D, E, A, B, W[3]);
P(B, C, D, E, A, W[4]);
P(A, B, C, D, E, W[5]);
P(E, A, B, C, D, W[6]);
P(D, E, A, B, C, W[7]);
P(C, D, E, A, B, W[8]);
P(B, C, D, E, A, W[9]);
P(A, B, C, D, E, W[10]);
P(E, A, B, C, D, W[11]);
P(D, E, A, B, C, W[12]);
P(C, D, E, A, B, W[13]);
P(B, C, D, E, A, W[14]);
P(A, B, C, D, E, W[15]);
P(E, A, B, C, D, R(16));
P(D, E, A, B, C, R(17));
P(C, D, E, A, B, R(18));
P(B, C, D, E, A, R(19));
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0x6ED9EBA1
P(A, B, C, D, E, R(20));
P(E, A, B, C, D, R(21));
P(D, E, A, B, C, R(22));
P(C, D, E, A, B, R(23));
P(B, C, D, E, A, R(24));
P(A, B, C, D, E, R(25));
P(E, A, B, C, D, R(26));
P(D, E, A, B, C, R(27));
P(C, D, E, A, B, R(28));
P(B, C, D, E, A, R(29));
P(A, B, C, D, E, R(30));
P(E, A, B, C, D, R(31));
P(D, E, A, B, C, R(32));
P(C, D, E, A, B, R(33));
P(B, C, D, E, A, R(34));
P(A, B, C, D, E, R(35));
P(E, A, B, C, D, R(36));
P(D, E, A, B, C, R(37));
P(C, D, E, A, B, R(38));
P(B, C, D, E, A, R(39));
#undef K
#undef F
#define F(x,y,z) ((x & y) | (z & (x | y)))
#define K 0x8F1BBCDC
P(A, B, C, D, E, R(40));
P(E, A, B, C, D, R(41));
P(D, E, A, B, C, R(42));
P(C, D, E, A, B, R(43));
P(B, C, D, E, A, R(44));
P(A, B, C, D, E, R(45));
P(E, A, B, C, D, R(46));
P(D, E, A, B, C, R(47));
P(C, D, E, A, B, R(48));
P(B, C, D, E, A, R(49));
P(A, B, C, D, E, R(50));
P(E, A, B, C, D, R(51));
P(D, E, A, B, C, R(52));
P(C, D, E, A, B, R(53));
P(B, C, D, E, A, R(54));
P(A, B, C, D, E, R(55));
P(E, A, B, C, D, R(56));
P(D, E, A, B, C, R(57));
P(C, D, E, A, B, R(58));
P(B, C, D, E, A, R(59));
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0xCA62C1D6
P(A, B, C, D, E, R(60));
P(E, A, B, C, D, R(61));
P(D, E, A, B, C, R(62));
P(C, D, E, A, B, R(63));
P(B, C, D, E, A, R(64));
P(A, B, C, D, E, R(65));
P(E, A, B, C, D, R(66));
P(D, E, A, B, C, R(67));
P(C, D, E, A, B, R(68));
P(B, C, D, E, A, R(69));
P(A, B, C, D, E, R(70));
P(E, A, B, C, D, R(71));
P(D, E, A, B, C, R(72));
P(C, D, E, A, B, R(73));
P(B, C, D, E, A, R(74));
P(A, B, C, D, E, R(75));
P(E, A, B, C, D, R(76));
P(D, E, A, B, C, R(77));
P(C, D, E, A, B, R(78));
P(B, C, D, E, A, R(79));
#undef K
#undef F
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
ctx->state[4] += E;
}
/*
* SHA-1 process buffer
*/
void sha1_update(sha1_context * ctx, const unsigned char *input, int ilen)
{
int fill;
unsigned long left;
if (ilen <= 0)
return;
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += (unsigned long) ilen;
ctx->total[0] &= 0xFFFFFFFF;
if (ctx->total[0] < (unsigned long) ilen)
ctx->total[1]++;
if (left && ilen >= fill) {
memcpy((void *) (ctx->buffer + left), (void *) input, fill);
sha1_process(ctx, ctx->buffer);
input += fill;
ilen -= fill;
left = 0;
}
while (ilen >= 64) {
sha1_process(ctx, input);
input += 64;
ilen -= 64;
}
if (ilen > 0) {
memcpy((void *) (ctx->buffer + left), (void *) input, ilen);
}
}
static const unsigned char sha1_padding[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* SHA-1 final digest
*/
void sha1_finish(sha1_context * ctx, unsigned char output[20])
{
unsigned long last, padn;
unsigned long high, low;
unsigned char msglen[8];
high = (ctx->total[0] >> 29)
| (ctx->total[1] << 3);
low = (ctx->total[0] << 3);
PUT_ULONG_BE(high, msglen, 0);
PUT_ULONG_BE(low, msglen, 4);
last = ctx->total[0] & 0x3F;
padn = (last < 56) ? (56 - last) : (120 - last);
sha1_update(ctx, (unsigned char *) sha1_padding, padn);
sha1_update(ctx, msglen, 8);
PUT_ULONG_BE(ctx->state[0], output, 0);
PUT_ULONG_BE(ctx->state[1], output, 4);
PUT_ULONG_BE(ctx->state[2], output, 8);
PUT_ULONG_BE(ctx->state[3], output, 12);
PUT_ULONG_BE(ctx->state[4], output, 16);
}
/*
* output = SHA-1( input buffer )
*/
void sha1(const unsigned char *input, int ilen, unsigned char output[20])
{
sha1_context ctx;
sha1_starts(&ctx);
sha1_update(&ctx, input, ilen);
sha1_finish(&ctx, output);
}
/*
* SHA-1 HMAC context setup
*/
void sha1_hmac_starts(sha1_context * ctx, const unsigned char *key, int keylen)
{
int i;
unsigned char sum[20];
if (keylen > 64) {
sha1(key, keylen, sum);
keylen = 20;
key = sum;
}
memset(ctx->ipad, 0x36, 64);
memset(ctx->opad, 0x5C, 64);
for (i = 0; i < keylen; i++) {
ctx->ipad[i] = (unsigned char) (ctx->ipad[i] ^ key[i]);
ctx->opad[i] = (unsigned char) (ctx->opad[i] ^ key[i]);
}
sha1_starts(ctx);
sha1_update(ctx, ctx->ipad, 64);
}
/*
* SHA-1 HMAC process buffer
*/
void sha1_hmac_update(sha1_context * ctx, const unsigned char *input, int ilen)
{
sha1_update(ctx, input, ilen);
}
/*
* SHA-1 HMAC final digest
*/
void sha1_hmac_finish(sha1_context * ctx, unsigned char output[20])
{
unsigned char tmpbuf[20];
sha1_finish(ctx, tmpbuf);
sha1_starts(ctx);
sha1_update(ctx, ctx->opad, 64);
sha1_update(ctx, tmpbuf, 20);
sha1_finish(ctx, output);
}
/*
* SHA1 HMAC context reset
*/
void sha1_hmac_reset(sha1_context * ctx)
{
sha1_starts(ctx);
sha1_update(ctx, ctx->ipad, 64);
}
/*
* output = HMAC-SHA-1( hmac key, input buffer )
*/
void sha1_hmac(const unsigned char *key, int keylen,
const unsigned char *input, int ilen, unsigned char output[20])
{
sha1_context ctx;
sha1_hmac_starts(&ctx, key, keylen);
sha1_hmac_update(&ctx, input, ilen);
sha1_hmac_finish(&ctx, output);
}
#ifndef min
#define min( a, b ) ( ((a) < (b)) ? (a) : (b) )
#endif
void PKCS5_PBKDF2_HMAC_SHA1(const unsigned char *password, size_t plen,
const unsigned char *salt, size_t slen,
const unsigned long iteration_count, const unsigned long key_length,
unsigned char *output)
{
sha1_context ctx;
sha1_starts(&ctx);
// Size of the generated digest
unsigned char md_size = 20;
unsigned char md1[20];
unsigned char work[20];
unsigned long counter = 1;
unsigned long generated_key_length = 0;
while (generated_key_length < key_length) {
// U1 ends up in md1 and work
unsigned char c[4];
c[0] = (counter >> 24) & 0xff;
c[1] = (counter >> 16) & 0xff;
c[2] = (counter >> 8) & 0xff;
c[3] = (counter >> 0) & 0xff;
sha1_hmac_starts(&ctx, password, plen);
sha1_hmac_update(&ctx, salt, slen);
sha1_hmac_update(&ctx, c, 4);
sha1_hmac_finish(&ctx, md1);
memcpy(work, md1, md_size);
unsigned long ic = 1;
for (ic = 1; ic < iteration_count; ic++) {
// U2 ends up in md1
sha1_hmac_starts(&ctx, password, plen);
sha1_hmac_update(&ctx, md1, md_size);
sha1_hmac_finish(&ctx, md1);
// U1 xor U2
unsigned long i = 0;
for (i = 0; i < md_size; i++) {
work[i] ^= md1[i];
}
// and so on until iteration_count
}
// Copy the generated bytes to the key
unsigned long bytes_to_write =
min((key_length - generated_key_length), md_size);
memcpy(output + generated_key_length, work, bytes_to_write);
generated_key_length += bytes_to_write;
++counter;
}
}
#if defined(TEST)
/*
* FIPS-180-1 test vectors
*/
static unsigned char sha1_test_buf[3][57] = {
{"abc"},
{"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
{""}
};
static const int sha1_test_buflen[3] = {
3, 56, 1000
};
static const unsigned char sha1_test_sum[3][20] = {
{0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D},
{0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1},
{0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F}
};
/*
* RFC 2202 test vectors
*/
static unsigned char sha1_hmac_test_key[7][26] = {
{"\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
"\x0B\x0B\x0B\x0B"},
{"Jefe"},
{"\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
"\xAA\xAA\xAA\xAA"},
{"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19"},
{"\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
"\x0C\x0C\x0C\x0C"},
{""}, /* 0xAA 80 times */
{""}
};
static const int sha1_hmac_test_keylen[7] = {
20, 4, 20, 25, 20, 80, 80
};
static unsigned char sha1_hmac_test_buf[7][74] = {
{"Hi There"},
{"what do ya want for nothing?"},
{"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"},
{"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"},
{"Test With Truncation"},
{"Test Using Larger Than Block-Size Key - Hash Key First"},
{"Test Using Larger Than Block-Size Key and Larger"
" Than One Block-Size Data"}
};
static const int sha1_hmac_test_buflen[7] = {
8, 28, 50, 50, 20, 54, 73
};
static const unsigned char sha1_hmac_test_sum[7][20] = {
{0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B,
0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00},
{0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74,
0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79},
{0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3,
0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3},
{0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84,
0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA},
{0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2,
0x7B, 0xE1},
{0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70,
0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12},
{0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B,
0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91}
};
typedef struct {
char *t;
char *p;
int plen;
char *s;
int slen;
int c;
int dkLen;
char dk[1024]; // Remember to set this to max dkLen
} testvector;
int do_test(testvector * tv)
{
printf("Started %s\n", tv->t);
fflush(stdout);
char *key = malloc(tv->dkLen);
if (key == 0) {
return -1;
}
PKCS5_PBKDF2_HMAC(tv->p, tv->plen, tv->s, tv->slen, tv->c,
tv->dkLen, key);
if (memcmp(tv->dk, key, tv->dkLen) != 0) {
// Failed
return -1;
}
return 0;
}
#ifdef DEBUG
static void print_hex(unsigned char *str, int len)
{
int i;
for (i = 0; i < len; ++i)
printf("%02x", str[i]);
printf("\n");
}
#endif
/*
* Checkup routine
*/
int main(int argc,char * argv[])
{
int verbose = 1;
int i, j, buflen;
unsigned char buf[1024];
unsigned char sha1sum[20];
sha1_context ctx;
/*
* SHA-1
*/
for (i = 0; i < 3; i++) {
if (verbose != 0)
printf(" SHA-1 test #%d: ", i + 1);
sha1_starts(&ctx);
if (i == 2) {
memset(buf, 'a', buflen = 1000);
for (j = 0; j < 1000; j++)
sha1_update(&ctx, buf, buflen);
} else
sha1_update(&ctx, sha1_test_buf[i],
sha1_test_buflen[i]);
sha1_finish(&ctx, sha1sum);
if (memcmp(sha1sum, sha1_test_sum[i], 20) != 0) {
if (verbose != 0)
printf("failed\n");
return (1);
}
if (verbose != 0)
printf("passed\n");
}
if (verbose != 0)
printf("\n");
for (i = 0; i < 7; i++) {
if (verbose != 0)
printf(" HMAC-SHA-1 test #%d: ", i + 1);
if (i == 5 || i == 6) {
memset(buf, '\xAA', buflen = 80);
sha1_hmac_starts(&ctx, buf, buflen);
} else
sha1_hmac_starts(&ctx, sha1_hmac_test_key[i],
sha1_hmac_test_keylen[i]);
sha1_hmac_update(&ctx, sha1_hmac_test_buf[i],
sha1_hmac_test_buflen[i]);
sha1_hmac_finish(&ctx, sha1sum);
buflen = (i == 4) ? 12 : 20;
if (memcmp(sha1sum, sha1_hmac_test_sum[i], buflen) != 0) {
if (verbose != 0)
printf("failed\n");
return (1);
}
if (verbose != 0)
printf("passed\n");
}
if (verbose != 0)
printf("\n");
// Test vectors from RFC 6070
testvector *tv = 0;
int res = 0;
/*
Input:
P = "password" (8 octets)
S = "salt" (4 octets)
c = 1
dkLen = 20
Output:
DK = 0c 60 c8 0f 96 1f 0e 71
f3 a9 b5 24 af 60 12 06
2f e0 37 a6 (20 octets)
*/
testvector t1 = {
"Test 1",
"password", 8, "salt", 4, 1, 20,
.dk = {0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71,
0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06,
0x2f, 0xe0, 0x37, 0xa6}
};
tv = &t1;
res = do_test(tv);
if (res != 0) {
printf("%s failed\n", tv->t);
return res;
}
/*
Input:
P = "password" (8 octets)
S = "salt" (4 octets)
c = 2
dkLen = 20
Output:
DK = ea 6c 01 4d c7 2d 6f 8c
cd 1e d9 2a ce 1d 41 f0
d8 de 89 57 (20 octets)
*/
testvector t2 = {
"Test 2",
"password", 8, "salt", 4, 2, 20,
{0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c,
0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0,
0xd8, 0xde, 0x89, 0x57}
};
tv = &t2;
res = do_test(tv);
if (res != 0) {
printf("%s failed\n", tv->t);
return res;
}
/*
Input:
P = "password" (8 octets)
S = "salt" (4 octets)
c = 4096
dkLen = 20
Output:
DK = 4b 00 79 01 b7 65 48 9a
be ad 49 d9 26 f7 21 d0
65 a4 29 c1 (20 octets)
*/
testvector t3 = {
"Test 3",
"password", 8, "salt", 4, 4096, 20,
{0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a,
0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0,
0x65, 0xa4, 0x29, 0xc1}
};
tv = &t3;
res = do_test(tv);
if (res != 0) {
printf("%s failed\n", tv->t);
return res;
}
/*
Input:
P = "password" (8 octets)
S = "salt" (4 octets)
c = 16777216
dkLen = 20
Output:
DK = ee fe 3d 61 cd 4d a4 e4
e9 94 5b 3d 6b a2 15 8c
26 34 e9 84 (20 octets)
*/
testvector t4 = {
"Test 4",
"password", 8, "salt", 4, 16777216, 20,
{0xee, 0xfe, 0x3d, 0x61, 0xcd, 0x4d, 0xa4, 0xe4,
0xe9, 0x94, 0x5b, 0x3d, 0x6b, 0xa2, 0x15, 0x8c,
0x26, 0x34, 0xe9, 0x84}
};
tv = &t4;
// res = do_test(tv);
if (res != 0) {
printf("%s failed\n", tv->t);
return res;
}
/*
Input:
P = "passwordPASSWORDpassword" (24 octets)
S = "saltSALTsaltSALTsaltSALTsaltSALTsalt" (36 octets)
c = 4096
dkLen = 25
Output:
DK = 3d 2e ec 4f e4 1c 84 9b
80 c8 d8 36 62 c0 e4 4a
8b 29 1a 96 4c f2 f0 70
38 (25 octets)
*/
testvector t5 = {
"Test 5",
"passwordPASSWORDpassword", 24,
"saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, 4096, 25,
{0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b,
0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a,
0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70,
0x38}
};
tv = &t5;
res = do_test(tv);
if (res != 0) {
printf("%s failed\n", tv->t);
return res;
}
/*
Input:
P = "pass\0word" (9 octets)
S = "sa\0lt" (5 octets)
c = 4096
dkLen = 16
Output:
DK = 56 fa 6a a7 55 48 09 9d
cc 37 d7 f0 34 25 e0 c3 (16 octets)
*/
testvector t6 = {
"Test 6",
"pass\0word", 9, "sa\0lt", 5, 4096, 16,
{0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d,
0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3,
}
};
tv = &t6;
res = do_test(tv);
if (res != 0) {
printf("%s failed\n", tv->t);
return res;
}
printf("All tests successful\n");
return 0;
}
#endif
/*
int main()
{
}*/

14
lib/pbkdf2-sha1.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void sha1(const unsigned char *input, int ilen, unsigned char output[20]);
void sha1_hmac(const unsigned char *key, int keylen, const unsigned char *input, int ilen, unsigned char output[20]);
void PKCS5_PBKDF2_HMAC_SHA1(const unsigned char *password, size_t plen,
const unsigned char *salt, size_t slen,
const unsigned long iteration_count, const unsigned long key_length,
unsigned char *output);

1124
lib/pbkdf2-sha256.cpp Normal file

File diff suppressed because it is too large Load Diff

28
lib/pbkdf2-sha256.h Normal file
View File

@ -0,0 +1,28 @@
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void PKCS5_PBKDF2_HMAC_SHA256(unsigned char *password, size_t plen,
unsigned char *salt, size_t slen,
const unsigned long iteration_count, const unsigned long key_length,
unsigned char *output);
//void sha2( const unsigned char *input, size_t ilen,unsigned char output[32], int is224 );
int hkdf_sha256_extract(
const unsigned char *salt, size_t salt_len,
const unsigned char *ikm, size_t ikm_len,
unsigned char *prk );
int hkdf_sha256_expand( const unsigned char *prk,
size_t prk_len, const unsigned char *info,
size_t info_len, unsigned char *okm, size_t okm_len );
int hkdf_sha256( const unsigned char *salt,
size_t salt_len, const unsigned char *ikm, size_t ikm_len,
const unsigned char *info, size_t info_len,
unsigned char *okm, size_t okm_len );

31
libev/CVS/Entries Normal file
View File

@ -0,0 +1,31 @@
/Changes/1.315/Wed Jun 21 14:42:30 2017//
/LICENSE/1.11/Thu Jan 16 11:51:05 2014//
/Makefile.am/1.9/Wed Dec 21 18:16:08 2011//
/README/1.21/Fri Mar 30 17:43:55 2012//
/README.embed/1.29/Sat Nov 24 10:10:26 2007//
/Symbols.ev/1.14/Tue Jan 11 13:45:28 2011//
/Symbols.event/1.4/Tue May 8 15:52:13 2012//
/autogen.sh/1.3/Mon May 30 15:28:54 2011//
/configure.ac/1.42/Wed Dec 28 04:22:06 2016//
/ev++.h/1.63/Fri Dec 1 06:37:30 2017//
/ev.3/1.107/Wed Jun 21 14:42:30 2017//
/ev.c/1.481/Thu Jun 1 20:25:50 2017//
/ev.h/1.187/Wed Dec 28 04:22:06 2016//
/ev.pod/1.441/Thu Jul 13 10:46:52 2017//
/ev_epoll.c/1.72/Wed Jun 21 14:42:30 2017//
/ev_kqueue.c/1.56/Thu Feb 18 04:48:05 2016//
/ev_poll.c/1.40/Thu Feb 18 04:48:05 2016//
/ev_port.c/1.29/Thu Feb 18 04:48:05 2016//
/ev_select.c/1.56/Thu Feb 18 04:48:05 2016//
/ev_vars.h/1.58/Tue Sep 9 21:51:35 2014//
/ev_win32.c/1.18/Thu Nov 12 07:02:37 2015//
/ev_wrap.h/1.38/Tue Nov 6 20:56:50 2012//
/event.c/1.52/Mon Apr 2 23:14:41 2012//
/event.h/1.26/Mon Apr 2 23:15:27 2012//
/event_compat.h/1.8/Wed Feb 16 08:02:51 2011//
/import_libevent/1.29/Tue Apr 15 04:34:07 2008//
/libev.m4/1.16/Mon Oct 28 12:36:44 2013//
/update_ev_c/1.2/Wed Jan 18 12:13:14 2012//
/update_ev_wrap/1.6/Sun May 6 13:09:29 2012//
/update_symbols/1.1/Wed Dec 19 01:59:29 2007//
D

1
libev/CVS/Repository Normal file
View File

@ -0,0 +1 @@
libev

1
libev/CVS/Root Normal file
View File

@ -0,0 +1 @@
:pserver:anonymous@cvs.schmorp.de/schmorpforge

517
libev/Changes Normal file
View File

@ -0,0 +1,517 @@
Revision history for libev, a high-performance and full-featured event loop.
- ANDROID => __ANDROID__ (reported by enh@google.com).
- disable epoll_create1 on android because it has broken header files
and google is unwilling to fix them (reported by enh@google.com).
4.24 Wed Dec 28 05:19:55 CET 2016
- bump version to 4.24, as the release tarball inexplicably
didn't have the right version in ev.h, even though the cvs-tagged
version did have the right one (reported by Ales Teska).
4.23 Wed Nov 16 18:23:41 CET 2016
- move some declarations at the beginning to help certain retarded
microsoft compilers, even though their documentation claims
otherwise (reported by Ruslan Osmanov).
4.22 Sun Dec 20 22:11:50 CET 2015
- when epoll detects unremovable fds in the fd set, rebuild
only the epoll descriptor, not the signal pipe, to avoid
SIGPIPE in ev_async_send. This doesn't solve it on fork,
so document what needs to be done in ev_loop_fork
(analyzed by Benjamin Mahler).
- remove superfluous sys/timeb.h include on win32
(analyzed by Jason Madden).
- updated libecb.
4.20 Sat Jun 20 13:01:43 CEST 2015
- prefer noexcept over throw () with C++ 11.
- update ecb.h due to incompatibilities with c11.
- fix a potential aliasing issue when reading and writing
watcher callbacks.
4.19 Thu Sep 25 08:18:25 CEST 2014
- ev.h wasn't valid C++ anymore, which tripped compilers other than
clang, msvc or gcc (analyzed by Raphael 'kena' Poss). Unfortunately,
C++ doesn't support typedefs for function pointers fully, so the affected
declarations have to spell out the types each time.
- when not using autoconf, tighten the check for clock_gettime and related
functionality.
4.18 Fri Sep 5 17:55:26 CEST 2014
- events on files were not always generated properly with the
epoll backend (testcase by Assaf Inbal).
- mark event pipe fd as cloexec after a fork (analyzed by Sami Farin).
- (ecb) support m68k, m88k and sh (patch by Miod Vallat).
- use a reasonable fallback for EV_NSIG instead of erroring out
when we can't detect the signal set size.
- in the absence of autoconf, do not use the clock syscall
on glibc >= 2.17 (avoids the syscall AND -lrt on systems
doing clock_gettime in userspace).
- ensure extern "C" function pointers are used for externally-visible
loop callbacks (not watcher callbacks yet).
- (ecb) work around memory barriers and volatile apparently both being
broken in visual studio 2008 and later (analysed and patch by Nicolas Noble).
4.15 Fri Mar 1 12:04:50 CET 2013
- destroying a non-default loop would stop the global waitpid
watcher (Denis Bilenko).
- queueing pending watchers of higher priority from a watcher now invokes
them in a timely fashion (reported by Denis Bilenko).
- add throw() to all libev functions that cannot throw exceptions, for
further code size decrease when compiling for C++.
- add throw () to callbacks that must not throw exceptions (allocator,
syserr, loop acquire/release, periodic reschedule cbs).
- fix event_base_loop return code, add event_get_callback, event_base_new,
event_base_get_method calls to improve libevent 1.x emulation and add
some libevent 2.x functionality (based on a patch by Jeff Davey).
- add more memory fences to fix a bug reported by Jeff Davey. Better
be overfenced than underprotected.
- ev_run now returns a boolean status (true meaning watchers are
still active).
- ev_once: undef EV_ERROR in ev_kqueue.c, to avoid clashing with
libev's EV_ERROR (reported by 191919).
- (ecb) add memory fence support for xlC (Darin McBride).
- (ecb) add memory fence support for gcc-mips (Anton Kirilov).
- (ecb) add memory fence support for gcc-alpha (Christian Weisgerber).
- work around some kernels losing file descriptors by leaking
the kqueue descriptor in the child.
- work around linux inotify not reporting IN_ATTRIB changes for directories
in many cases.
- include sys/syscall.h instead of plain syscall.h.
- check for io watcher loops in ev_verify, check for the most
common reported usage bug in ev_io_start.
- choose socket vs. WSASocket at compiletime using EV_USE_WSASOCKET.
- always use WSASend/WSARecv directly on windows, hoping that this
works in all cases (unlike read/write/send/recv...).
- try to detect signals around a fork faster (test program by
Denis Bilenko).
- work around recent glibc versions that leak memory in realloc.
- rename ev::embed::set to ev::embed::set_embed to avoid clashing
the watcher base set (loop) method.
- rewrite the async/signal pipe logic to always keep a valid fd, which
simplifies (and hopefully correctifies :) the race checking
on fork, at the cost of one extra fd.
- add fat, msdos, jffs2, ramfs, ntfs and btrfs to the list of
inotify-supporting filesystems.
- move orig_CFLAGS assignment to after AC_INIT, as newer autoconf
versions ignore it before
(https://bugzilla.redhat.com/show_bug.cgi?id=908096).
- add some untested android support.
- enum expressions must be of type int (reported by Juan Pablo L).
4.11 Sat Feb 4 19:52:39 CET 2012
- INCOMPATIBLE CHANGE: ev_timer_again now clears the pending status, as
was documented already, but not implemented in the repeating case.
- new compiletime symbols: EV_NO_SMP and EV_NO_THREADS.
- fix a race where the workaround against the epoll fork bugs
caused signals to not be handled anymore.
- correct backend_fudge for most backends, and implement a windows
specific workaround to avoid looping because we call both
select and Sleep, both with different time resolutions.
- document range and guarantees of ev_sleep.
- document reasonable ranges for periodics interval and offset.
- rename backend_fudge to backend_mintime to avoid future confusion :)
- change the default periodic reschedule function to hopefully be more
exact and correct even in corner cases or in the far future.
- do not rely on -lm anymore: use it when available but use our
own floor () if it is missing. This should make it easier to embed,
as no external libraries are required.
- strategically import macros from libecb and mark rarely-used functions
as cache-cold (saving almost 2k code size on typical amd64 setups).
- add Symbols.ev and Symbols.event files, that were missing.
- fix backend_mintime value for epoll (was 1/1024, is 1/1000 now).
- fix #3 "be smart about timeouts" to not "deadlock" when
timeout == now, also improve the section overall.
- avoid "AVOIDING FINISHING BEFORE RETURNING" idiom.
- support new EV_API_STATIC mode to make all libev symbols
static.
- supply default CFLAGS of -g -O3 with gcc when original CFLAGS
were empty.
4.04 Wed Feb 16 09:01:51 CET 2011
- fix two problems in the native win32 backend, where reuse of fd's
with different underlying handles caused handles not to be removed
or added to the select set (analyzed and tested by Bert Belder).
- do no rely on ceil() in ev_e?poll.c.
- backport libev to HP-UX versions before 11 v3.
- configure did not detect nanosleep and clock_gettime properly when
they are available in the libc (as opposed to -lrt).
4.03 Tue Jan 11 14:37:25 CET 2011
- officially support polling files with all backends.
- support files, /dev/zero etc. the same way as select in the epoll
backend, by generating events on our own.
- ports backend: work around solaris bug 6874410 and many related ones
(EINTR, maybe more), with no performance loss (note that the solaris
bug report is actually wrong, reality is far more bizarre and broken
than that).
- define EV_READ/EV_WRITE as macros in event.h, as some programs use
#ifdef to test for them.
- new (experimental) function: ev_feed_signal.
- new (to become default) EVFLAG_NOSIGMASK flag.
- new EVBACKEND_MASK symbol.
- updated COMMON IDIOMS SECTION.
4.01 Fri Nov 5 21:51:29 CET 2010
- automake fucked it up, apparently, --add-missing -f is not quite enough
to make it update its files, so 4.00 didn't install ev++.h and
event.h on make install. grrr.
- ev_loop(count|depth) didn't return anything (Robin Haberkorn).
- change EV_UNDEF to 0xffffffff to silence some overzealous compilers.
- use "(libev) " prefix for all libev error messages now.
4.00 Mon Oct 25 12:32:12 CEST 2010
- "PORTING FROM LIBEV 3.X TO 4.X" (in ev.pod) is recommended reading.
- ev_embed_stop did not correctly stop the watcher (very good
testcase by Vladimir Timofeev).
- ev_run will now always update the current loop time - it erroneously
didn't when idle watchers were active, causing timers not to fire.
- fix a bug where a timeout of zero caused the timer not to fire
in the libevent emulation (testcase by Péter Szabó).
- applied win32 fixes by Michael Lenaghan (also James Mansion).
- replace EV_MINIMAL by EV_FEATURES.
- prefer EPOLL_CTL_ADD over EPOLL_CTL_MOD in some more cases, as it
seems the former is *much* faster than the latter.
- linux kernel version detection (for inotify bug workarounds)
did not work properly.
- reduce the number of spurious wake-ups with the ports backend.
- remove dependency on sys/queue.h on freebsd (patch by Vanilla Hsu).
- do async init within ev_async_start, not ev_async_set, which avoids
an API quirk where the set function must be called in the C++ API
even when there is nothing to set.
- add (undocumented) EV_ENABLE when adding events with kqueue,
this might help with OS X, which seems to need it despite documenting
not to need it (helpfully pointed out by Tilghman Lesher).
- do not use poll by default on freebsd, it's broken (what isn't
on freebsd...).
- allow to embed epoll on kernels >= 2.6.32.
- configure now prepends -O3, not appends it, so one can still
override it.
- ev.pod: greatly expanded the portability section, added a porting
section, a description of watcher states and made lots of minor fixes.
- disable poll backend on AIX, the poll header spams the namespace
and it's not worth working around dead platforms (reported
and analyzed by Aivars Kalvans).
- improve header file compatibility of the standalone eventfd code
in an obscure case.
- implement EV_AVOID_STDIO option.
- do not use sscanf to parse linux version number (smaller, faster,
no sscanf dependency).
- new EV_CHILD_ENABLE and EV_SIGNAL_ENABLE configurable settings.
- update libev.m4 HAVE_CLOCK_SYSCALL test for newer glibcs.
- add section on accept() problems to the manpage.
- rename EV_TIMEOUT to EV_TIMER.
- rename ev_loop_count/depth/verify/loop/unloop.
- remove ev_default_destroy and ev_default_fork.
- switch to two-digit minor version.
- work around an apparent gentoo compiler bug.
- define _DARWIN_UNLIMITED_SELECT. just so.
- use enum instead of #define for most constants.
- improve compatibility to older C++ compilers.
- (experimental) ev_run/ev_default_loop/ev_break/ev_loop_new have now
default arguments when compiled as C++.
- enable automake dependency tracking.
- ev_loop_new no longer leaks memory when loop creation failed.
- new ev_cleanup watcher type.
3.9 Thu Dec 31 07:59:59 CET 2009
- signalfd is no longer used by default and has to be requested
explicitly - this means that easy to catch bugs become hard to
catch race conditions, but the users have spoken.
- point out the unspecified signal mask in the documentation, and
that this is a race condition regardless of EV_SIGNALFD.
- backport inotify code to C89.
- inotify file descriptors could leak into child processes.
- ev_stat watchers could keep an erroneous extra ref on the loop,
preventing exit when unregistering all watchers (testcases
provided by ry@tinyclouds.org).
- implement EV_WIN32_HANDLE_TO_FD and EV_WIN32_CLOSE_FD configuration
symbols to make it easier for apps to do their own fd management.
- support EV_IDLE_ENABLE being disabled in ev++.h
(patch by Didier Spezia).
- take advantage of inotify_init1, if available, to set cloexec/nonblock
on fd creation, to avoid races.
- the signal handling pipe wasn't always initialised under windows
(analysed by lekma).
- changed minimum glibc requirement from glibc 2.9 to 2.7, for
signalfd.
- add missing string.h include (Denis F. Latypoff).
- only replace ev_stat.prev when we detect an actual difference,
so prev is (almost) always different to attr. this might
have caused the problems with 04_stat.t.
- add ev::timer->remaining () method to C++ API.
3.8 Sun Aug 9 14:30:45 CEST 2009
- incompatible change: do not necessarily reset signal handler
to SIG_DFL when a sighandler is stopped.
- ev_default_destroy did not properly free or zero some members,
potentially causing crashes and memory corruption on repeated
ev_default_destroy/ev_default_loop calls.
- take advantage of signalfd on GNU/Linux systems.
- document that the signal mask might be in an unspecified
state when using libev's signal handling.
- take advantage of some GNU/Linux calls to set cloexec/nonblock
on fd creation, to avoid race conditions.
3.7 Fri Jul 17 16:36:32 CEST 2009
- ev_unloop and ev_loop wrongly used a global variable to exit loops,
instead of using a per-loop variable (bug caught by accident...).
- the ev_set_io_collect_interval interpretation has changed.
- add new functionality: ev_set_userdata, ev_userdata,
ev_set_invoke_pending_cb, ev_set_loop_release_cb,
ev_invoke_pending, ev_pending_count, together with a long example
about thread locking.
- add ev_timer_remaining (as requested by Denis F. Latypoff).
- add ev_loop_depth.
- calling ev_unloop in fork/prepare watchers will no longer poll
for new events.
- Denis F. Latypoff corrected many typos in example code snippets.
- honor autoconf detection of EV_USE_CLOCK_SYSCALL, also double-
check that the syscall number is available before trying to
use it (reported by ry@tinyclouds).
- use GetSystemTimeAsFileTime instead of _timeb on windows, for
slightly higher accuracy.
- properly declare ev_loop_verify and ev_now_update even when
!EV_MULTIPLICITY.
- do not compile in any priority code when EV_MAXPRI == EV_MINPRI.
- support EV_MINIMAL==2 for a reduced API.
- actually 0-initialise struct sigaction when installing signals.
- add section on hibernate and stopped processes to ev_timer docs.
3.6 Tue Apr 28 02:49:30 CEST 2009
- multiple timers becoming ready within an event loop iteration
will be invoked in the "correct" order now.
- do not leave the event loop early just because we have no active
watchers, fixing a problem when embedding a kqueue loop
that has active kernel events but no registered watchers
(reported by blacksand blacksand).
- correctly zero the idx values for arrays, so destroying and
reinitialising the default loop actually works (patch by
Malek Hadj-Ali).
- implement ev_suspend and ev_resume.
- new EV_CUSTOM revents flag for use by applications.
- add documentation section about priorities.
- add a glossary to the documentation.
- extend the ev_fork description slightly.
- optimize a jump out of call_pending.
3.53 Sun Feb 15 02:38:20 CET 2009
- fix a bug in event pipe creation on win32 that would cause a
failed assertion on event loop creation (patch by Malek Hadj-Ali).
- probe for CLOCK_REALTIME support at runtime as well and fall
back to gettimeofday if there is an error, to support older
operating systems with newer header files/libraries.
- prefer gettimeofday over clock_gettime with USE_CLOCK_SYSCALL
(default most everywhere), otherwise not.
3.52 Wed Jan 7 21:43:02 CET 2009
- fix compilation of select backend in fd_set mode when NFDBITS is
missing (to get it to compile on QNX, reported by Rodrigo Campos).
- better select-nfds handling when select backend is in fd_set mode.
- diagnose fd_set overruns when select backend is in fd_set mode.
- due to a thinko, instead of disabling everything but
select on the borked OS X platform, everything but select was
allowed (reported by Emanuele Giaquinta).
- actually verify that local and remote port are matching in
libev's socketpair emulation, which makes denial-of-service
attacks harder (but not impossible - it's windows). Make sure
it even works under vista, which thinks that getpeer/sockname
should return fantasy port numbers.
- include "libev" in all assertion messages for potentially
clearer diagnostics.
- event_get_version (libevent compatibility) returned
a useless string instead of the expected version string
(patch by W.C.A. Wijngaards).
3.51 Wed Dec 24 23:00:11 CET 2008
- fix a bug where an inotify watcher was added twice, causing
freezes on hash collisions (reported and analysed by Graham Leggett).
- new config symbol, EV_USE_CLOCK_SYSCALL, to make libev use
a direct syscall - slower, but no dependency on librt et al.
- assume negative return values != -1 signals success of port_getn
(http://cvs.epicsol.org/cgi/viewcvs.cgi/epic5/source/newio.c?rev=1.52)
(no known failure reports, but it doesn't hurt).
- fork detection in ev_embed now stops and restarts the watcher
automatically.
- EXPERIMENTAL: default the method to operator () in ev++.h,
to make it nicer to use functors (requested by Benedek László).
- fixed const object callbacks in ev++.h.
- replaced loop_ref argument of watcher.set (loop) by a direct
ev_loop * in ev++.h, to avoid clashes with functor patch.
- do not try to watch the empty string via inotify.
- inotify watchers could be leaked under certain circumstances.
- OS X 10.5 is actually even more broken than earlier versions,
so fall back to select on that piece of garbage.
- fixed some weirdness in the ev_embed documentation.
3.49 Wed Nov 19 11:26:53 CET 2008
- ev_stat watchers will now use inotify as a mere hint on
kernels <2.6.25, or if the filesystem is not in the
"known to be good" list.
- better mingw32 compatibility (it's not as borked as native win32)
(analysed by Roger Pack).
- include stdio.h in the example program, as too many people are
confused by the weird C language otherwise. I guess the next thing
I get told is that the "..." ellipses in the examples don't compile
with their C compiler.
3.48 Thu Oct 30 09:02:37 CET 2008
- further optimise away the EPOLL_CTL_ADD/MOD combo in the epoll
backend by assuming the kernel event mask hasn't changed if
ADD fails with EEXIST.
- work around spurious event notification bugs in epoll by using
a 32-bit generation counter. recreate kernel state if we receive
spurious notifications or unwanted events. this is very costly,
but I didn't come up with this horrible design.
- use memset to initialise most arrays now and do away with the
init functions.
- expand time-out strategies into a "Be smart about timeouts" section.
- drop the "struct" from all ev_watcher declarations in the
documentation and did other clarifications (yeah, it was a mistake
to have a struct AND a function called ev_loop).
- fix a bug where ev_default would not initialise the default
loop again after it was destroyed with ev_default_destroy.
- rename syserr to ev_syserr to avoid name clashes when embedding,
do similar changes for event.c.
3.45 Tue Oct 21 21:59:26 CEST 2008
- disable inotify usage on linux <2.6.25, as it is broken
(reported by Yoann Vandoorselaere).
- ev_stat erroneously would try to add inotify watchers
even when inotify wasn't available (this should only
have a performance impact).
- ev_once now passes both timeout and io to the callback if both
occur concurrently, instead of giving timeouts precedence.
- disable EV_USE_INOTIFY when sys/inotify.h is too old.
3.44 Mon Sep 29 05:18:39 CEST 2008
- embed watchers now automatically invoke ev_loop_fork on the
embedded loop when the parent loop forks.
- new function: ev_now_update (loop).
- verify_watcher was not marked static.
- improve the "associating..." manpage section.
- documentation tweaks here and there.
3.43 Sun Jul 6 05:34:41 CEST 2008
- include more include files on windows to get struct _stati64
(reported by Chris Hulbert, but doesn't quite fix his issue).
- add missing #include <io.h> in ev.c on windows (reported by
Matt Tolton).
3.42 Tue Jun 17 12:12:07 CEST 2008
- work around yet another windows bug: FD_SET actually adds fd's
multiple times to the fd_*SET*, despite official MSN docs claiming
otherwise. Reported and well-analysed by Matt Tolton.
- define NFDBITS to 0 when EV_SELECT_IS_WINSOCKET to make it compile
(reported any analysed by Chris Hulbert).
- fix a bug in ev_ebadf (this function is only used to catch
programming errors in the libev user). reported by Matt Tolton.
- fix a bug in fd_intern on win32 (could lead to compile errors
under some circumstances, but would work correctly if it compiles).
reported by Matt Tolton.
- (try to) work around missing lstat on windows.
- pass in the write fd set as except fd set under windows. windows
is so uncontrollably lame that it requires this. this means that
switching off oobinline is not supported (but tcp/ip doesn't
have oob, so that would be stupid anyways.
- use posix module symbol to auto-detect monotonic clock presence
and some other default values.
3.41 Fri May 23 18:42:54 CEST 2008
- work around an obscure bug in winsocket select: if you
provide only empty fd sets then select returns WSAEINVAL. how sucky.
- improve timer scheduling stability and reduce use of time_epsilon.
- use 1-based 2-heap for EV_MINIMAL, simplifies code, reduces
codesize and makes for better cache-efficiency.
- use 3-based 4-heap for !EV_MINIMAL. this makes better use
of cpu cache lines and gives better growth behaviour than
2-based heaps.
- cache timestamp within heap for !EV_MINIMAL, to avoid random
memory accesses.
- document/add EV_USE_4HEAP and EV_HEAP_CACHE_AT.
- fix a potential aliasing issue in ev_timer_again.
- add/document ev_periodic_at, retract direct access to ->at.
- improve ev_stat docs.
- add portability requirements section.
- fix manpage headers etc.
- normalise WSA error codes to lower range on windows.
- add consistency check code that can be called automatically
or on demand to check for internal structures (ev_loop_verify).
3.31 Wed Apr 16 20:45:04 CEST 2008
- added last minute fix for ev_poll.c by Brandon Black.
3.3 Wed Apr 16 19:04:10 CEST 2008
- event_base_loopexit should return 0 on success
(W.C.A. Wijngaards).
- added linux eventfd support.
- try to autodetect epoll and inotify support
by libc header version if not using autoconf.
- new symbols: EV_DEFAULT_UC and EV_DEFAULT_UC_.
- declare functions defined in ev.h as inline if
C99 or gcc are available.
- enable inlining with gcc versions 2 and 3.
- work around broken poll implementations potentially
not clearing revents field in ev_poll (Brandon Black)
(no such systems are known at this time).
- work around a bug in realloc on openbsd and darwin,
also makes the erroneous valgrind complaints
go away (noted by various people).
- fix ev_async_pending, add c++ wrapper for ev_async
(based on patch sent by Johannes Deisenhofer).
- add sensible set method to ev::embed.
- made integer constants type int in ev.h.
3.2 Wed Apr 2 17:11:19 CEST 2008
- fix a 64 bit overflow issue in the select backend,
by using fd_mask instead of int for the mask.
- rename internal sighandler to avoid clash with very old perls.
- entering ev_loop will not clear the ONESHOT or NONBLOCKING
flags of any outer loops anymore.
- add ev_async_pending.
3.1 Thu Mar 13 13:45:22 CET 2008
- implement ev_async watchers.
- only initialise signal pipe on demand.
- make use of sig_atomic_t configurable.
- improved documentation.
3.0 Mon Jan 28 13:14:47 CET 2008
- API/ABI bump to version 3.0.
- ev++.h includes "ev.h" by default now, not <ev.h>.
- slightly improved documentation.
- speed up signal detection after a fork.
- only optionally return trace status changed in ev_child
watchers.
- experimental (and undocumented) loop wrappers for ev++.h.
2.01 Tue Dec 25 08:04:41 CET 2007
- separate Changes file.
- fix ev_path_set => ev_stat_set typo.
- remove event_compat.h from the libev tarball.
- change how include files are found.
- doc updates.
- update licenses, explicitly allow for GPL relicensing.
2.0 Sat Dec 22 17:47:03 CET 2007
- new ev_sleep, ev_set_(io|timeout)_collect_interval.
- removed epoll from embeddable fd set.
- fix embed watchers.
- renamed ev_embed.loop to other.
- added exported Symbol tables.
- undefine member wrapper macros at the end of ev.c.
- respect EV_H in ev++.h.
1.86 Tue Dec 18 02:36:57 CET 2007
- fix memleak on loop destroy (not relevant for perl).
1.85 Fri Dec 14 20:32:40 CET 2007
- fix some aliasing issues w.r.t. timers and periodics
(not relevant for perl).
(for historic versions refer to EV/Changes, found in the Perl interface)
0.1 Wed Oct 31 21:31:48 CET 2007
- original version; hacked together in <24h.

37
libev/LICENSE Normal file
View File

@ -0,0 +1,37 @@
All files in libev are
Copyright (c)2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Alternatively, the contents of this package may be used under the terms
of the GNU General Public License ("GPL") version 2 or any later version,
in which case the provisions of the GPL are applicable instead of the
above. If you wish to allow the use of your version of this package only
under the terms of the GPL and not to allow others to use your version of
this file under the BSD license, indicate your decision by deleting the
provisions above and replace them with the notice and other provisions
required by the GPL in this and the other files of this package. If you do
not delete the provisions above, a recipient may use your version of this
file under either the BSD or the GPL.

20
libev/Makefile.am Normal file
View File

@ -0,0 +1,20 @@
AUTOMAKE_OPTIONS = foreign
VERSION_INFO = 4:0:0
EXTRA_DIST = LICENSE Changes libev.m4 autogen.sh \
ev_vars.h ev_wrap.h \
ev_epoll.c ev_select.c ev_poll.c ev_kqueue.c ev_port.c ev_win32.c \
ev.3 ev.pod Symbols.ev Symbols.event
man_MANS = ev.3
include_HEADERS = ev.h ev++.h event.h
lib_LTLIBRARIES = libev.la
libev_la_SOURCES = ev.c event.c
libev_la_LDFLAGS = -version-info $(VERSION_INFO)
ev.3: ev.pod
pod2man -n LIBEV -r "libev-$(VERSION)" -c "libev - high performance full featured event loop" -s3 <$< >$@

58
libev/README Normal file
View File

@ -0,0 +1,58 @@
libev is a high-performance event loop/event model with lots of features.
(see benchmark at http://libev.schmorp.de/bench.html)
ABOUT
Homepage: http://software.schmorp.de/pkg/libev
Mailinglist: libev@lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Library Documentation: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod
Libev is modelled (very losely) after libevent and the Event perl
module, but is faster, scales better and is more correct, and also more
featureful. And also smaller. Yay.
Some of the specialties of libev not commonly found elsewhere are:
- extensive and detailed, readable documentation (not doxygen garbage).
- fully supports fork, can detect fork in various ways and automatically
re-arms kernel mechanisms that do not support fork.
- highly optimised select, poll, epoll, kqueue and event ports backends.
- filesystem object (path) watching (with optional linux inotify support).
- wallclock-based times (using absolute time, cron-like).
- relative timers/timeouts (handle time jumps).
- fast intra-thread communication between multiple
event loops (with optional fast linux eventfd backend).
- extremely easy to embed (fully documented, no dependencies,
autoconf supported but optional).
- very small codebase, no bloated library, simple code.
- fully extensible by being able to plug into the event loop,
integrate other event loops, integrate other event loop users.
- very little memory use (small watchers, small event loop data).
- optional C++ interface allowing method and function callbacks
at no extra memory or runtime overhead.
- optional Perl interface with similar characteristics (capable
of running Glib/Gtk2 on libev).
- support for other languages (multiple C++ interfaces, D, Ruby,
Python) available from third-parties.
Examples of programs that embed libev: the EV perl module, node.js,
auditd, rxvt-unicode, gvpe (GNU Virtual Private Ethernet), the
Deliantra MMORPG server (http://www.deliantra.net/), Rubinius (a
next-generation Ruby VM), the Ebb web server, the Rev event toolkit.
CONTRIBUTORS
libev was written and designed by Marc Lehmann and Emanuele Giaquinta.
The following people sent in patches or made other noteworthy
contributions to the design (for minor patches, see the Changes
file. If I forgot to include you, please shout at me, it was an
accident):
W.C.A. Wijngaards
Christopher Layne
Chris Brody

3
libev/README.embed Normal file
View File

@ -0,0 +1,3 @@
This file is now included in the main libev documentation, see
http://cvs.schmorp.de/libev/ev.html

73
libev/Symbols.ev Normal file
View File

@ -0,0 +1,73 @@
ev_async_send
ev_async_start
ev_async_stop
ev_backend
ev_break
ev_check_start
ev_check_stop
ev_child_start
ev_child_stop
ev_cleanup_start
ev_cleanup_stop
ev_clear_pending
ev_default_loop
ev_default_loop_ptr
ev_depth
ev_embed_start
ev_embed_stop
ev_embed_sweep
ev_embeddable_backends
ev_feed_event
ev_feed_fd_event
ev_feed_signal
ev_feed_signal_event
ev_fork_start
ev_fork_stop
ev_idle_start
ev_idle_stop
ev_invoke
ev_invoke_pending
ev_io_start
ev_io_stop
ev_iteration
ev_loop_destroy
ev_loop_fork
ev_loop_new
ev_now
ev_now_update
ev_once
ev_pending_count
ev_periodic_again
ev_periodic_start
ev_periodic_stop
ev_prepare_start
ev_prepare_stop
ev_recommended_backends
ev_ref
ev_resume
ev_run
ev_set_allocator
ev_set_invoke_pending_cb
ev_set_io_collect_interval
ev_set_loop_release_cb
ev_set_syserr_cb
ev_set_timeout_collect_interval
ev_set_userdata
ev_signal_start
ev_signal_stop
ev_sleep
ev_stat_start
ev_stat_stat
ev_stat_stop
ev_supported_backends
ev_suspend
ev_time
ev_timer_again
ev_timer_remaining
ev_timer_start
ev_timer_stop
ev_unref
ev_userdata
ev_verify
ev_version_major
ev_version_minor

Some files were not shown because too many files have changed in this diff Show More