diff options
author | Ron Yorston <rmy@pobox.com> | 2018-11-28 10:28:18 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2018-11-28 10:28:18 +0000 |
commit | 2a69a2200a141c1504b662eca64b802cdab71b12 (patch) | |
tree | eab0cc01852db237a26052a83c8f582ed92b7cd9 /networking | |
parent | 97ca1f4b955f486cd26461cb09185335483d2921 (diff) | |
parent | 572dfb8e78323b9837f7c5e3369ee233a440b8f2 (diff) | |
download | busybox-w32-2a69a2200a141c1504b662eca64b802cdab71b12.tar.gz busybox-w32-2a69a2200a141c1504b662eca64b802cdab71b12.tar.bz2 busybox-w32-2a69a2200a141c1504b662eca64b802cdab71b12.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'networking')
-rw-r--r-- | networking/brctl.c | 13 | ||||
-rw-r--r-- | networking/nbd-client.c | 230 | ||||
-rw-r--r-- | networking/ntpd.c | 268 | ||||
-rw-r--r-- | networking/tls.c | 1116 | ||||
-rw-r--r-- | networking/tls.h | 13 | ||||
-rw-r--r-- | networking/tls_aes.c | 41 | ||||
-rw-r--r-- | networking/tls_aes.h | 8 | ||||
-rw-r--r-- | networking/tls_aesgcm.c | 151 | ||||
-rw-r--r-- | networking/tls_aesgcm.h | 11 | ||||
-rw-r--r-- | networking/tls_fe.c | 611 | ||||
-rw-r--r-- | networking/tls_fe.h | 7 | ||||
-rw-r--r-- | networking/tls_rsa.c | 2 | ||||
-rw-r--r-- | networking/tls_rsa.h | 14 | ||||
-rw-r--r-- | networking/udhcp/d6_dhcpc.c | 9 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 9 | ||||
-rw-r--r-- | networking/wget.c | 25 |
16 files changed, 2112 insertions, 416 deletions
diff --git a/networking/brctl.c b/networking/brctl.c index 5d5f0af30..ba4a714f8 100644 --- a/networking/brctl.c +++ b/networking/brctl.c | |||
@@ -241,7 +241,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv) | |||
241 | 241 | ||
242 | #if ENABLE_FEATURE_BRCTL_SHOW | 242 | #if ENABLE_FEATURE_BRCTL_SHOW |
243 | if (key == ARG_show) { /* show */ | 243 | if (key == ARG_show) { /* show */ |
244 | char brname[IFNAMSIZ]; | 244 | char buf[IFNAMSIZ]; |
245 | int bridx[MAX_PORTS]; | 245 | int bridx[MAX_PORTS]; |
246 | int i, num; | 246 | int i, num; |
247 | arm_ioctl(args, BRCTL_GET_BRIDGES, | 247 | arm_ioctl(args, BRCTL_GET_BRIDGES, |
@@ -249,19 +249,18 @@ int brctl_main(int argc UNUSED_PARAM, char **argv) | |||
249 | num = xioctl(fd, SIOCGIFBR, args); | 249 | num = xioctl(fd, SIOCGIFBR, args); |
250 | puts("bridge name\tbridge id\t\tSTP enabled\tinterfaces"); | 250 | puts("bridge name\tbridge id\t\tSTP enabled\tinterfaces"); |
251 | for (i = 0; i < num; i++) { | 251 | for (i = 0; i < num; i++) { |
252 | char ifname[IFNAMSIZ]; | ||
253 | int j, tabs; | 252 | int j, tabs; |
254 | struct __bridge_info bi; | 253 | struct __bridge_info bi; |
255 | unsigned char *x; | 254 | unsigned char *x; |
256 | 255 | ||
257 | if (!if_indextoname(bridx[i], brname)) | 256 | if (!if_indextoname(bridx[i], buf)) |
258 | bb_perror_msg_and_die("can't get bridge name for index %d", i); | 257 | bb_perror_msg_and_die("can't get bridge name for index %d", i); |
259 | strncpy_IFNAMSIZ(ifr.ifr_name, brname); | 258 | strncpy_IFNAMSIZ(ifr.ifr_name, buf); |
260 | 259 | ||
261 | arm_ioctl(args, BRCTL_GET_BRIDGE_INFO, | 260 | arm_ioctl(args, BRCTL_GET_BRIDGE_INFO, |
262 | (unsigned long) &bi, 0); | 261 | (unsigned long) &bi, 0); |
263 | xioctl(fd, SIOCDEVPRIVATE, &ifr); | 262 | xioctl(fd, SIOCDEVPRIVATE, &ifr); |
264 | printf("%s\t\t", brname); | 263 | printf("%s\t\t", buf); |
265 | 264 | ||
266 | /* print bridge id */ | 265 | /* print bridge id */ |
267 | x = (unsigned char *) &bi.bridge_id; | 266 | x = (unsigned char *) &bi.bridge_id; |
@@ -280,13 +279,13 @@ int brctl_main(int argc UNUSED_PARAM, char **argv) | |||
280 | for (j = 0; j < MAX_PORTS; j++) { | 279 | for (j = 0; j < MAX_PORTS; j++) { |
281 | if (!ifidx[j]) | 280 | if (!ifidx[j]) |
282 | continue; | 281 | continue; |
283 | if (!if_indextoname(ifidx[j], ifname)) | 282 | if (!if_indextoname(ifidx[j], buf)) |
284 | bb_perror_msg_and_die("can't get interface name for index %d", j); | 283 | bb_perror_msg_and_die("can't get interface name for index %d", j); |
285 | if (tabs) | 284 | if (tabs) |
286 | printf("\t\t\t\t\t"); | 285 | printf("\t\t\t\t\t"); |
287 | else | 286 | else |
288 | tabs = 1; | 287 | tabs = 1; |
289 | printf("\t\t%s\n", ifname); | 288 | printf("\t\t%s\n", buf); |
290 | } | 289 | } |
291 | if (!tabs) /* bridge has no interfaces */ | 290 | if (!tabs) /* bridge has no interfaces */ |
292 | bb_putchar('\n'); | 291 | bb_putchar('\n'); |
diff --git a/networking/nbd-client.c b/networking/nbd-client.c index bedb01a1c..103756b59 100644 --- a/networking/nbd-client.c +++ b/networking/nbd-client.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include "libbb.h" | 16 | #include "libbb.h" |
17 | #include <netinet/tcp.h> | 17 | #include <netinet/tcp.h> |
18 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
19 | #include <getopt.h> | ||
19 | 20 | ||
20 | #define NBD_SET_SOCK _IO(0xab, 0) | 21 | #define NBD_SET_SOCK _IO(0xab, 0) |
21 | #define NBD_SET_BLKSIZE _IO(0xab, 1) | 22 | #define NBD_SET_BLKSIZE _IO(0xab, 1) |
@@ -27,57 +28,144 @@ | |||
27 | #define NBD_SET_SIZE_BLOCKS _IO(0xab, 7) | 28 | #define NBD_SET_SIZE_BLOCKS _IO(0xab, 7) |
28 | #define NBD_DISCONNECT _IO(0xab, 8) | 29 | #define NBD_DISCONNECT _IO(0xab, 8) |
29 | #define NBD_SET_TIMEOUT _IO(0xab, 9) | 30 | #define NBD_SET_TIMEOUT _IO(0xab, 9) |
31 | #define NBD_SET_FLAGS _IO(0xab, 10) | ||
30 | 32 | ||
31 | //usage:#define nbdclient_trivial_usage | 33 | //usage:#define nbdclient_trivial_usage |
32 | //usage: "HOST PORT BLOCKDEV" | 34 | //usage: "{ [-b BLKSIZE] [-N NAME] [-t SEC] [-p] HOST [PORT] | -d } BLOCKDEV" |
33 | //usage:#define nbdclient_full_usage "\n\n" | 35 | //usage:#define nbdclient_full_usage "\n\n" |
34 | //usage: "Connect to HOST and provide a network block device on BLOCKDEV" | 36 | //usage: "Connect to HOST and provide network block device on BLOCKDEV" |
35 | 37 | ||
36 | //TODO: more compat with nbd-client version 2.9.13 - | 38 | //TODO: more compat with nbd-client version 3.17 - |
37 | //Usage: nbd-client [bs=blocksize] [timeout=sec] host port nbd_device [-swap] [-persist] [-nofork] | 39 | //nbd-client host [ port ] nbd-device [ -connections num ] [ -sdp ] [ -swap ] |
38 | //Or : nbd-client -d nbd_device | 40 | // [ -persist ] [ -nofork ] [ -nonetlink ] [ -systemd-mark ] |
39 | //Or : nbd-client -c nbd_device | 41 | // [ -block-size block size ] [ -timeout seconds ] [ -name name ] |
40 | //Default value for blocksize is 1024 (recommended for ethernet) | 42 | // [ -certfile certfile ] [ -keyfile keyfile ] [ -cacertfile cacertfile ] |
43 | // [ -tlshostname hostname ] | ||
44 | //nbd-client -unix path nbd-device [ -connections num ] [ -sdp ] [ -swap ] | ||
45 | // [ -persist ] [ -nofork ] [ -nonetlink ] [ -systemd-mark ] | ||
46 | // [ -block-size block size ] [ -timeout seconds ] [ -name name ] | ||
47 | //nbd-client nbd-device | ||
48 | //nbd-client -d nbd-device | ||
49 | //nbd-client -c nbd-device | ||
50 | //nbd-client -l host [ port ] | ||
51 | //nbd-client [ -netlink ] -l host | ||
52 | // | ||
53 | //Default value for blocksize is 4096 | ||
41 | //Allowed values for blocksize are 512,1024,2048,4096 | 54 | //Allowed values for blocksize are 512,1024,2048,4096 |
42 | //Note, that kernel 2.4.2 and older ones do not work correctly with | ||
43 | //blocksizes other than 1024 without patches | ||
44 | 55 | ||
45 | int nbdclient_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 56 | int nbdclient_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
46 | int nbdclient_main(int argc UNUSED_PARAM, char **argv) | 57 | int nbdclient_main(int argc, char **argv) |
47 | { | 58 | { |
48 | unsigned long timeout = 0; | ||
49 | #if BB_MMU | 59 | #if BB_MMU |
50 | int nofork = 0; | 60 | bool nofork; |
51 | #endif | 61 | #endif |
52 | char *host, *port, *device; | 62 | bool opt_d; |
63 | bool opt_p; | ||
64 | const char *host, *port, *device; | ||
65 | const char *name; | ||
66 | unsigned blksize, size_blocks; | ||
67 | unsigned timeout; | ||
68 | int ch; | ||
53 | struct nbd_header_t { | 69 | struct nbd_header_t { |
54 | uint64_t magic1; // "NBDMAGIC" | 70 | uint64_t magic1; // "NBDMAGIC" |
55 | uint64_t magic2; // 0x420281861253 big endian | 71 | uint64_t magic2; // old style: 0x420281861253 big endian |
72 | // // new style: 0x49484156454F5054 (IHAVEOPT) | ||
73 | } nbd_header; | ||
74 | struct old_nbd_header_t { | ||
56 | uint64_t devsize; | 75 | uint64_t devsize; |
57 | uint32_t flags; | 76 | uint32_t flags; |
58 | char data[124]; | 77 | char data[124]; |
59 | } nbd_header; | 78 | } old_nbd_header; |
79 | struct new_nbd_header_t { | ||
80 | uint64_t devsize; | ||
81 | uint16_t transmission_flags; | ||
82 | char data[124]; | ||
83 | } new_nbd_header; | ||
84 | struct nbd_opt_t { | ||
85 | uint64_t magic; | ||
86 | uint32_t opt; | ||
87 | uint32_t len; | ||
88 | } nbd_opts; | ||
60 | 89 | ||
61 | BUILD_BUG_ON(offsetof(struct nbd_header_t, data) != 8+8+8+4); | 90 | static const struct option long_options[] = { |
91 | { "block-size", required_argument, NULL, 'b' }, | ||
92 | { "timeout" , required_argument, NULL, 't' }, | ||
93 | { "name" , required_argument, NULL, 'n' }, | ||
94 | { "persist" , no_argument , NULL, 'p' }, | ||
95 | { NULL } | ||
96 | }; | ||
62 | 97 | ||
63 | // Parse command line stuff (just a stub now) | 98 | BUILD_BUG_ON(offsetof(struct old_nbd_header_t, data) != 8 + 4); |
64 | if (!argv[1] || !argv[2] || !argv[3] || argv[4]) | 99 | BUILD_BUG_ON(offsetof(struct new_nbd_header_t, data) != 8 + 2); |
65 | bb_show_usage(); | ||
66 | 100 | ||
67 | #if !BB_MMU | 101 | #if !BB_MMU |
68 | bb_daemonize_or_rexec(DAEMON_CLOSE_EXTRA_FDS, argv); | 102 | bb_daemonize_or_rexec(DAEMON_CLOSE_EXTRA_FDS, argv); |
69 | #endif | 103 | #endif |
70 | 104 | ||
71 | host = argv[1]; | 105 | // Parse args. nbd-client uses stupid "one-dash long options" style :( |
72 | port = argv[2]; | 106 | // Even though short forms (-b,-t,-N,-p) exist for all long opts, |
73 | device = argv[3]; | 107 | // older manpages only contained long forms, which probably resulted |
108 | // in many scripts using them. | ||
109 | blksize = 4096; | ||
110 | timeout = 0; | ||
111 | name = ""; // use of "" instead of NULL simplifies strlen() later | ||
112 | opt_d = opt_p = 0; | ||
113 | while ((ch = getopt_long_only(argc, argv, "dN:", long_options, NULL)) != -1) { | ||
114 | switch (ch) { | ||
115 | case 'p': // -persist | ||
116 | opt_p = 1; | ||
117 | break; | ||
118 | case 'd': // -d | ||
119 | opt_d = 1; | ||
120 | break; | ||
121 | case 'b': // -block-size | ||
122 | blksize = xatou(optarg); | ||
123 | break; | ||
124 | case 't': // -timeout | ||
125 | timeout = xatou(optarg); | ||
126 | break; | ||
127 | case 'N': // -N | ||
128 | case 'n': // -name | ||
129 | name = optarg; | ||
130 | break; | ||
131 | default: | ||
132 | bb_show_usage(); | ||
133 | } | ||
134 | } | ||
135 | argv += optind; | ||
136 | |||
137 | if (opt_d) { // -d | ||
138 | if (argv[0] && !argv[1]) { | ||
139 | int nbd = xopen(argv[0], O_RDWR); | ||
140 | ioctl(nbd, NBD_DISCONNECT); | ||
141 | ioctl(nbd, NBD_CLEAR_SOCK); | ||
142 | if (ENABLE_FEATURE_CLEAN_UP) | ||
143 | close(nbd); | ||
144 | return 0; | ||
145 | } | ||
146 | bb_show_usage(); | ||
147 | } | ||
148 | |||
149 | // Allow only argv[] of: HOST [PORT] BLOCKDEV | ||
150 | if (!argv[0] || !argv[1] || (argv[2] && argv[3])) { | ||
151 | bb_show_usage(); | ||
152 | } | ||
74 | 153 | ||
75 | // Repeat until spanked (-persist behavior) | 154 | host = argv[0]; |
76 | for (;;) { | 155 | port = argv[2] ? argv[1] : "10809"; |
156 | device = argv[2] ? argv[2] : argv[1]; | ||
157 | |||
158 | // Repeat until spanked if -persist | ||
159 | #if BB_MMU | ||
160 | nofork = 0; | ||
161 | #endif | ||
162 | do { | ||
77 | int sock, nbd; | 163 | int sock, nbd; |
78 | int ro; | 164 | int ro; |
165 | int proto_new; // 0 for old, 1 for new | ||
166 | char *data; | ||
79 | 167 | ||
80 | // Make sure the /dev/nbd exists | 168 | // Make sure BLOCKDEV exists |
81 | nbd = xopen(device, O_RDWR); | 169 | nbd = xopen(device, O_RDWR); |
82 | 170 | ||
83 | // Find and connect to server | 171 | // Find and connect to server |
@@ -85,40 +173,95 @@ int nbdclient_main(int argc UNUSED_PARAM, char **argv) | |||
85 | setsockopt_1(sock, IPPROTO_TCP, TCP_NODELAY); | 173 | setsockopt_1(sock, IPPROTO_TCP, TCP_NODELAY); |
86 | 174 | ||
87 | // Log on to the server | 175 | // Log on to the server |
88 | xread(sock, &nbd_header, 8+8+8+4 + 124); | 176 | xread(sock, &nbd_header, 8 + 8); |
89 | if (memcmp(&nbd_header.magic1, "NBDMAGIC""\x00\x00\x42\x02\x81\x86\x12\x53", 16) != 0) | 177 | if (memcmp(&nbd_header.magic1, "NBDMAGIC", |
178 | sizeof(nbd_header.magic1)) != 0 | ||
179 | ) { | ||
180 | bb_error_msg_and_die("login failed"); | ||
181 | } | ||
182 | if (memcmp(&nbd_header.magic2, | ||
183 | "\x00\x00\x42\x02\x81\x86\x12\x53", | ||
184 | sizeof(nbd_header.magic2)) == 0 | ||
185 | ) { | ||
186 | proto_new = 0; | ||
187 | } else if (memcmp(&nbd_header.magic2, "IHAVEOPT", 8) == 0) { | ||
188 | proto_new = 1; | ||
189 | } else { | ||
90 | bb_error_msg_and_die("login failed"); | 190 | bb_error_msg_and_die("login failed"); |
191 | } | ||
192 | |||
193 | if (!proto_new) { | ||
194 | xread(sock, &old_nbd_header, | ||
195 | sizeof(old_nbd_header.devsize) + | ||
196 | sizeof(old_nbd_header.flags) + | ||
197 | sizeof(old_nbd_header.data)); | ||
198 | size_blocks = SWAP_BE64(old_nbd_header.devsize) / blksize; | ||
199 | ioctl(nbd, NBD_SET_BLKSIZE, (unsigned long) blksize); | ||
200 | ioctl(nbd, NBD_SET_SIZE_BLOCKS, size_blocks); | ||
201 | ioctl(nbd, NBD_CLEAR_SOCK); | ||
202 | ro = !!(old_nbd_header.flags & htons(2)); | ||
203 | data = old_nbd_header.data; | ||
204 | } else { | ||
205 | unsigned namelen; | ||
206 | uint16_t handshake_flags; | ||
207 | |||
208 | xread(sock, &handshake_flags, sizeof(handshake_flags)); | ||
209 | xwrite(sock, &const_int_0, sizeof(const_int_0)); // client_flags | ||
210 | |||
211 | memcpy(&nbd_opts.magic, "IHAVEOPT", | ||
212 | sizeof(nbd_opts.magic)); | ||
213 | nbd_opts.opt = htonl(1); // NBD_OPT_EXPORT_NAME | ||
214 | namelen = strlen(name); | ||
215 | nbd_opts.len = htonl(namelen); | ||
216 | xwrite(sock, &nbd_opts, | ||
217 | sizeof(nbd_opts.magic) + | ||
218 | sizeof(nbd_opts.opt) + | ||
219 | sizeof(nbd_opts.len)); | ||
220 | xwrite(sock, name, namelen); | ||
91 | 221 | ||
92 | // Set 4k block size. Everything uses that these days | 222 | xread(sock, &new_nbd_header, |
93 | ioctl(nbd, NBD_SET_BLKSIZE, 4096); | 223 | sizeof(new_nbd_header.devsize) + |
94 | ioctl(nbd, NBD_SET_SIZE_BLOCKS, SWAP_BE64(nbd_header.devsize) / 4096); | 224 | sizeof(new_nbd_header.transmission_flags) + |
95 | ioctl(nbd, NBD_CLEAR_SOCK); | 225 | sizeof(new_nbd_header.data)); |
226 | size_blocks = SWAP_BE64(new_nbd_header.devsize) / blksize; | ||
227 | ioctl(nbd, NBD_SET_BLKSIZE, (unsigned long) blksize); | ||
228 | ioctl(nbd, NBD_SET_SIZE_BLOCKS, size_blocks); | ||
229 | ioctl(nbd, NBD_CLEAR_SOCK); | ||
230 | ioctl(nbd, NBD_SET_FLAGS, | ||
231 | ntohs(new_nbd_header.transmission_flags)); | ||
232 | ro = !!(new_nbd_header.transmission_flags & htons(2)); | ||
233 | data = new_nbd_header.data; | ||
234 | } | ||
96 | 235 | ||
97 | // If the sucker was exported read only, respect that locally | 236 | if (ioctl(nbd, BLKROSET, &ro) < 0) { |
98 | ro = (nbd_header.flags & SWAP_BE32(2)) / SWAP_BE32(2); | ||
99 | if (ioctl(nbd, BLKROSET, &ro) < 0) | ||
100 | bb_perror_msg_and_die("BLKROSET"); | 237 | bb_perror_msg_and_die("BLKROSET"); |
238 | } | ||
101 | 239 | ||
102 | if (timeout) | 240 | if (timeout) { |
103 | if (ioctl(nbd, NBD_SET_TIMEOUT, timeout)) | 241 | if (ioctl(nbd, NBD_SET_TIMEOUT, (unsigned long) timeout)) { |
104 | bb_perror_msg_and_die("NBD_SET_TIMEOUT"); | 242 | bb_perror_msg_and_die("NBD_SET_TIMEOUT"); |
105 | if (ioctl(nbd, NBD_SET_SOCK, sock)) | 243 | } |
106 | bb_perror_msg_and_die("NBD_SET_SOCK"); | 244 | } |
107 | 245 | ||
108 | // if (swap) mlockall(MCL_CURRENT|MCL_FUTURE); | 246 | if (ioctl(nbd, NBD_SET_SOCK, sock)) { |
247 | bb_perror_msg_and_die("NBD_SET_SOCK"); | ||
248 | } | ||
109 | 249 | ||
250 | //if (swap) mlockall(MCL_CURRENT|MCL_FUTURE); | ||
110 | #if BB_MMU | 251 | #if BB_MMU |
111 | // Open the device to force reread of the partition table. | 252 | // Open the device to force reread of the partition table. |
112 | // Need to do it in a separate process, since open(device) | 253 | // Need to do it in a separate process, since open(device) |
113 | // needs some other process to sit in ioctl(nbd, NBD_DO_IT). | 254 | // needs some other process to sit in ioctl(nbd, NBD_DO_IT). |
114 | if (fork() == 0) { | 255 | if (fork() == 0) { |
256 | /* child */ | ||
115 | char *s = strrchr(device, '/'); | 257 | char *s = strrchr(device, '/'); |
116 | sprintf(nbd_header.data, "/sys/block/%.32s/pid", s ? s + 1 : device); | 258 | sprintf(data, "/sys/block/%.32s/pid", s ? s + 1 : device); |
117 | // Is it up yet? | 259 | // Is it up yet? |
118 | for (;;) { | 260 | for (;;) { |
119 | int fd = open(nbd_header.data, O_RDONLY); | 261 | int fd = open(data, O_RDONLY); |
120 | if (fd >= 0) { | 262 | if (fd >= 0) { |
121 | //close(fd); | 263 | if (ENABLE_FEATURE_CLEAN_UP) |
264 | close(fd); | ||
122 | break; | 265 | break; |
123 | } | 266 | } |
124 | sleep(1); | 267 | sleep(1); |
@@ -133,7 +276,6 @@ int nbdclient_main(int argc UNUSED_PARAM, char **argv) | |||
133 | nofork = 1; | 276 | nofork = 1; |
134 | } | 277 | } |
135 | #endif | 278 | #endif |
136 | |||
137 | // This turns us (the process that calls this ioctl) | 279 | // This turns us (the process that calls this ioctl) |
138 | // into a dedicated NBD request handler. | 280 | // into a dedicated NBD request handler. |
139 | // We block here for a long time. | 281 | // We block here for a long time. |
@@ -148,7 +290,7 @@ int nbdclient_main(int argc UNUSED_PARAM, char **argv) | |||
148 | 290 | ||
149 | close(sock); | 291 | close(sock); |
150 | close(nbd); | 292 | close(nbd); |
151 | } | 293 | } while (opt_p); |
152 | 294 | ||
153 | return 0; | 295 | return 0; |
154 | } | 296 | } |
diff --git a/networking/ntpd.c b/networking/ntpd.c index 1ebdc34c3..041cac762 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -62,13 +62,20 @@ | |||
62 | //config: help | 62 | //config: help |
63 | //config: Make ntpd look in /etc/ntp.conf for peers. Only "server address" | 63 | //config: Make ntpd look in /etc/ntp.conf for peers. Only "server address" |
64 | //config: is supported. | 64 | //config: is supported. |
65 | //config: | ||
66 | //config:config FEATURE_NTP_AUTH | ||
67 | //config: bool "Support md5/sha1 message authentication codes" | ||
68 | //config: default y | ||
69 | //config: depends on NTPD | ||
65 | 70 | ||
66 | //applet:IF_NTPD(APPLET(ntpd, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 71 | //applet:IF_NTPD(APPLET(ntpd, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
67 | 72 | ||
68 | //kbuild:lib-$(CONFIG_NTPD) += ntpd.o | 73 | //kbuild:lib-$(CONFIG_NTPD) += ntpd.o |
69 | 74 | ||
70 | //usage:#define ntpd_trivial_usage | 75 | //usage:#define ntpd_trivial_usage |
71 | //usage: "[-dnqNw"IF_FEATURE_NTPD_SERVER("l -I IFACE")"] [-S PROG] [-p PEER]..." | 76 | //usage: "[-dnqNw"IF_FEATURE_NTPD_SERVER("l] [-I IFACE")"] [-S PROG]" |
77 | //usage: IF_NOT_FEATURE_NTP_AUTH(" [-p PEER]...") | ||
78 | //usage: IF_FEATURE_NTP_AUTH(" [-k KEYFILE] [-p [keyno:N:]PEER]...") | ||
72 | //usage:#define ntpd_full_usage "\n\n" | 79 | //usage:#define ntpd_full_usage "\n\n" |
73 | //usage: "NTP client/server\n" | 80 | //usage: "NTP client/server\n" |
74 | //usage: "\n -d Verbose (may be repeated)" | 81 | //usage: "\n -d Verbose (may be repeated)" |
@@ -76,8 +83,16 @@ | |||
76 | //usage: "\n -q Quit after clock is set" | 83 | //usage: "\n -q Quit after clock is set" |
77 | //usage: "\n -N Run at high priority" | 84 | //usage: "\n -N Run at high priority" |
78 | //usage: "\n -w Do not set time (only query peers), implies -n" | 85 | //usage: "\n -w Do not set time (only query peers), implies -n" |
79 | //usage: "\n -S PROG Run PROG after stepping time, stratum change, and every 11 mins" | 86 | //usage: "\n -S PROG Run PROG after stepping time, stratum change, and every 11 min" |
87 | //usage: IF_NOT_FEATURE_NTP_AUTH( | ||
80 | //usage: "\n -p PEER Obtain time from PEER (may be repeated)" | 88 | //usage: "\n -p PEER Obtain time from PEER (may be repeated)" |
89 | //usage: ) | ||
90 | //usage: IF_FEATURE_NTP_AUTH( | ||
91 | //usage: "\n -k FILE Key file (ntp.keys compatible)" | ||
92 | //usage: "\n -p [keyno:NUM:]PEER" | ||
93 | //usage: "\n Obtain time from PEER (may be repeated)" | ||
94 | //usage: "\n Use key NUM for authentication" | ||
95 | //usage: ) | ||
81 | //usage: IF_FEATURE_NTPD_CONF( | 96 | //usage: IF_FEATURE_NTPD_CONF( |
82 | //usage: "\n If -p is not given, 'server HOST' lines" | 97 | //usage: "\n If -p is not given, 'server HOST' lines" |
83 | //usage: "\n from /etc/ntp.conf are used" | 98 | //usage: "\n from /etc/ntp.conf are used" |
@@ -228,14 +243,18 @@ | |||
228 | /* Parameter averaging constant */ | 243 | /* Parameter averaging constant */ |
229 | #define AVG 4 | 244 | #define AVG 4 |
230 | 245 | ||
246 | #define MAX_KEY_NUMBER 65535 | ||
247 | #define KEYID_SIZE sizeof(uint32_t) | ||
231 | 248 | ||
232 | enum { | 249 | enum { |
233 | NTP_VERSION = 4, | 250 | NTP_VERSION = 4, |
234 | NTP_MAXSTRATUM = 15, | 251 | NTP_MAXSTRATUM = 15, |
235 | 252 | ||
236 | NTP_DIGESTSIZE = 16, | 253 | NTP_MD5_DIGESTSIZE = 16, |
237 | NTP_MSGSIZE_NOAUTH = 48, | 254 | NTP_MSGSIZE_NOAUTH = 48, |
238 | NTP_MSGSIZE = (NTP_MSGSIZE_NOAUTH + 4 + NTP_DIGESTSIZE), | 255 | NTP_MSGSIZE_MD5_AUTH = NTP_MSGSIZE_NOAUTH + KEYID_SIZE + NTP_MD5_DIGESTSIZE, |
256 | NTP_SHA1_DIGESTSIZE = 20, | ||
257 | NTP_MSGSIZE_SHA1_AUTH = NTP_MSGSIZE_NOAUTH + KEYID_SIZE + NTP_SHA1_DIGESTSIZE, | ||
239 | 258 | ||
240 | /* Status Masks */ | 259 | /* Status Masks */ |
241 | MODE_MASK = (7 << 0), | 260 | MODE_MASK = (7 << 0), |
@@ -288,7 +307,7 @@ typedef struct { | |||
288 | l_fixedpt_t m_rectime; | 307 | l_fixedpt_t m_rectime; |
289 | l_fixedpt_t m_xmttime; | 308 | l_fixedpt_t m_xmttime; |
290 | uint32_t m_keyid; | 309 | uint32_t m_keyid; |
291 | uint8_t m_digest[NTP_DIGESTSIZE]; | 310 | uint8_t m_digest[ENABLE_FEATURE_NTP_AUTH ? NTP_SHA1_DIGESTSIZE : NTP_MD5_DIGESTSIZE]; |
292 | } msg_t; | 311 | } msg_t; |
293 | 312 | ||
294 | typedef struct { | 313 | typedef struct { |
@@ -297,9 +316,26 @@ typedef struct { | |||
297 | double d_dispersion; | 316 | double d_dispersion; |
298 | } datapoint_t; | 317 | } datapoint_t; |
299 | 318 | ||
319 | #if ENABLE_FEATURE_NTP_AUTH | ||
320 | enum { | ||
321 | HASH_MD5, | ||
322 | HASH_SHA1, | ||
323 | }; | ||
324 | typedef struct { | ||
325 | unsigned id; //try uint16_t? | ||
326 | smalluint type; | ||
327 | smalluint msg_size; | ||
328 | smalluint key_length; | ||
329 | char key[0]; | ||
330 | } key_entry_t; | ||
331 | #endif | ||
332 | |||
300 | typedef struct { | 333 | typedef struct { |
301 | len_and_sockaddr *p_lsa; | 334 | len_and_sockaddr *p_lsa; |
302 | char *p_dotted; | 335 | char *p_dotted; |
336 | #if ENABLE_FEATURE_NTP_AUTH | ||
337 | key_entry_t *key_entry; | ||
338 | #endif | ||
303 | int p_fd; | 339 | int p_fd; |
304 | int datapoint_idx; | 340 | int datapoint_idx; |
305 | uint32_t lastpkt_refid; | 341 | uint32_t lastpkt_refid; |
@@ -337,13 +373,14 @@ enum { | |||
337 | OPT_q = (1 << 1), | 373 | OPT_q = (1 << 1), |
338 | OPT_N = (1 << 2), | 374 | OPT_N = (1 << 2), |
339 | OPT_x = (1 << 3), | 375 | OPT_x = (1 << 3), |
376 | OPT_k = (1 << 4) * ENABLE_FEATURE_NTP_AUTH, | ||
340 | /* Insert new options above this line. */ | 377 | /* Insert new options above this line. */ |
341 | /* Non-compat options: */ | 378 | /* Non-compat options: */ |
342 | OPT_w = (1 << 4), | 379 | OPT_w = (1 << (4+ENABLE_FEATURE_NTP_AUTH)), |
343 | OPT_p = (1 << 5), | 380 | OPT_p = (1 << (5+ENABLE_FEATURE_NTP_AUTH)), |
344 | OPT_S = (1 << 6), | 381 | OPT_S = (1 << (6+ENABLE_FEATURE_NTP_AUTH)), |
345 | OPT_l = (1 << 7) * ENABLE_FEATURE_NTPD_SERVER, | 382 | OPT_l = (1 << (7+ENABLE_FEATURE_NTP_AUTH)) * ENABLE_FEATURE_NTPD_SERVER, |
346 | OPT_I = (1 << 8) * ENABLE_FEATURE_NTPD_SERVER, | 383 | OPT_I = (1 << (8+ENABLE_FEATURE_NTP_AUTH)) * ENABLE_FEATURE_NTPD_SERVER, |
347 | /* We hijack some bits for other purposes */ | 384 | /* We hijack some bits for other purposes */ |
348 | OPT_qq = (1 << 31), | 385 | OPT_qq = (1 << 31), |
349 | }; | 386 | }; |
@@ -816,8 +853,12 @@ resolve_peer_hostname(peer_t *p) | |||
816 | return lsa; | 853 | return lsa; |
817 | } | 854 | } |
818 | 855 | ||
856 | #if !ENABLE_FEATURE_NTP_AUTH | ||
857 | #define add_peers(s, key_entry) \ | ||
858 | add_peers(s) | ||
859 | #endif | ||
819 | static void | 860 | static void |
820 | add_peers(const char *s) | 861 | add_peers(const char *s, key_entry_t *key_entry) |
821 | { | 862 | { |
822 | llist_t *item; | 863 | llist_t *item; |
823 | peer_t *p; | 864 | peer_t *p; |
@@ -846,6 +887,7 @@ add_peers(const char *s) | |||
846 | } | 887 | } |
847 | } | 888 | } |
848 | 889 | ||
890 | IF_FEATURE_NTP_AUTH(p->key_entry = key_entry;) | ||
849 | llist_add_to(&G.ntp_peers, p); | 891 | llist_add_to(&G.ntp_peers, p); |
850 | G.peer_cnt++; | 892 | G.peer_cnt++; |
851 | } | 893 | } |
@@ -870,6 +912,48 @@ do_sendto(int fd, | |||
870 | return 0; | 912 | return 0; |
871 | } | 913 | } |
872 | 914 | ||
915 | #if ENABLE_FEATURE_NTP_AUTH | ||
916 | static void | ||
917 | hash(key_entry_t *key_entry, const msg_t *msg, uint8_t *output) | ||
918 | { | ||
919 | union { | ||
920 | md5_ctx_t m; | ||
921 | sha1_ctx_t s; | ||
922 | } ctx; | ||
923 | unsigned hash_size = sizeof(*msg) - sizeof(msg->m_keyid) - sizeof(msg->m_digest); | ||
924 | |||
925 | switch (key_entry->type) { | ||
926 | case HASH_MD5: | ||
927 | md5_begin(&ctx.m); | ||
928 | md5_hash(&ctx.m, key_entry->key, key_entry->key_length); | ||
929 | md5_hash(&ctx.m, msg, hash_size); | ||
930 | md5_end(&ctx.m, output); | ||
931 | break; | ||
932 | default: /* it's HASH_SHA1 */ | ||
933 | sha1_begin(&ctx.s); | ||
934 | sha1_hash(&ctx.s, key_entry->key, key_entry->key_length); | ||
935 | sha1_hash(&ctx.s, msg, hash_size); | ||
936 | sha1_end(&ctx.s, output); | ||
937 | break; | ||
938 | } | ||
939 | } | ||
940 | |||
941 | static void | ||
942 | hash_peer(peer_t *p) | ||
943 | { | ||
944 | p->p_xmt_msg.m_keyid = htonl(p->key_entry->id); | ||
945 | hash(p->key_entry, &p->p_xmt_msg, p->p_xmt_msg.m_digest); | ||
946 | } | ||
947 | |||
948 | static int | ||
949 | hashes_differ(peer_t *p, const msg_t *msg) | ||
950 | { | ||
951 | uint8_t digest[NTP_SHA1_DIGESTSIZE]; | ||
952 | hash(p->key_entry, msg, digest); | ||
953 | return memcmp(digest, msg->m_digest, p->key_entry->msg_size - NTP_MSGSIZE_NOAUTH - KEYID_SIZE); | ||
954 | } | ||
955 | #endif | ||
956 | |||
873 | static void | 957 | static void |
874 | send_query_to_peer(peer_t *p) | 958 | send_query_to_peer(peer_t *p) |
875 | { | 959 | { |
@@ -946,9 +1030,18 @@ send_query_to_peer(peer_t *p) | |||
946 | */ | 1030 | */ |
947 | p->reachable_bits <<= 1; | 1031 | p->reachable_bits <<= 1; |
948 | 1032 | ||
1033 | #if ENABLE_FEATURE_NTP_AUTH | ||
1034 | if (p->key_entry) | ||
1035 | hash_peer(p); | ||
949 | if (do_sendto(p->p_fd, /*from:*/ NULL, /*to:*/ &p->p_lsa->u.sa, /*addrlen:*/ p->p_lsa->len, | 1036 | if (do_sendto(p->p_fd, /*from:*/ NULL, /*to:*/ &p->p_lsa->u.sa, /*addrlen:*/ p->p_lsa->len, |
950 | &p->p_xmt_msg, NTP_MSGSIZE_NOAUTH) == -1 | 1037 | &p->p_xmt_msg, !p->key_entry ? NTP_MSGSIZE_NOAUTH : p->key_entry->msg_size) == -1 |
951 | ) { | 1038 | ) |
1039 | #else | ||
1040 | if (do_sendto(p->p_fd, /*from:*/ NULL, /*to:*/ &p->p_lsa->u.sa, /*addrlen:*/ p->p_lsa->len, | ||
1041 | &p->p_xmt_msg, NTP_MSGSIZE_NOAUTH) == -1 | ||
1042 | ) | ||
1043 | #endif | ||
1044 | { | ||
952 | close(p->p_fd); | 1045 | close(p->p_fd); |
953 | p->p_fd = -1; | 1046 | p->p_fd = -1; |
954 | /* | 1047 | /* |
@@ -1924,10 +2017,21 @@ recv_and_process_peer_pkt(peer_t *p) | |||
1924 | bb_perror_msg_and_die("recv(%s) error", p->p_dotted); | 2017 | bb_perror_msg_and_die("recv(%s) error", p->p_dotted); |
1925 | } | 2018 | } |
1926 | 2019 | ||
1927 | if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE) { | 2020 | #if ENABLE_FEATURE_NTP_AUTH |
2021 | if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE_MD5_AUTH && size != NTP_MSGSIZE_SHA1_AUTH) { | ||
2022 | bb_error_msg("malformed packet received from %s", p->p_dotted); | ||
2023 | return; | ||
2024 | } | ||
2025 | if (p->key_entry && hashes_differ(p, &msg)) { | ||
2026 | bb_error_msg("invalid cryptographic hash received from %s", p->p_dotted); | ||
2027 | return; | ||
2028 | } | ||
2029 | #else | ||
2030 | if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE_MD5_AUTH) { | ||
1928 | bb_error_msg("malformed packet received from %s", p->p_dotted); | 2031 | bb_error_msg("malformed packet received from %s", p->p_dotted); |
1929 | return; | 2032 | return; |
1930 | } | 2033 | } |
2034 | #endif | ||
1931 | 2035 | ||
1932 | if (msg.m_orgtime.int_partl != p->p_xmt_msg.m_xmttime.int_partl | 2036 | if (msg.m_orgtime.int_partl != p->p_xmt_msg.m_xmttime.int_partl |
1933 | || msg.m_orgtime.fractionl != p->p_xmt_msg.m_xmttime.fractionl | 2037 | || msg.m_orgtime.fractionl != p->p_xmt_msg.m_xmttime.fractionl |
@@ -2135,7 +2239,12 @@ recv_and_process_client_pkt(void /*int fd*/) | |||
2135 | from = xzalloc(to->len); | 2239 | from = xzalloc(to->len); |
2136 | 2240 | ||
2137 | size = recv_from_to(G_listen_fd, &msg, sizeof(msg), MSG_DONTWAIT, from, &to->u.sa, to->len); | 2241 | size = recv_from_to(G_listen_fd, &msg, sizeof(msg), MSG_DONTWAIT, from, &to->u.sa, to->len); |
2138 | if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE) { | 2242 | #if ENABLE_FEATURE_NTP_AUTH |
2243 | if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE_MD5_AUTH && size != NTP_MSGSIZE_SHA1_AUTH) | ||
2244 | #else | ||
2245 | if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE_MD5_AUTH) | ||
2246 | #endif | ||
2247 | { | ||
2139 | char *addr; | 2248 | char *addr; |
2140 | if (size < 0) { | 2249 | if (size < 0) { |
2141 | if (errno == EAGAIN) | 2250 | if (errno == EAGAIN) |
@@ -2278,6 +2387,19 @@ recv_and_process_client_pkt(void /*int fd*/) | |||
2278 | * with the -g and -q options. See the tinker command for other options. | 2387 | * with the -g and -q options. See the tinker command for other options. |
2279 | * Note: The kernel time discipline is disabled with this option. | 2388 | * Note: The kernel time discipline is disabled with this option. |
2280 | */ | 2389 | */ |
2390 | #if ENABLE_FEATURE_NTP_AUTH | ||
2391 | static key_entry_t * | ||
2392 | find_key_entry(llist_t *key_entries, unsigned id) | ||
2393 | { | ||
2394 | while (key_entries) { | ||
2395 | key_entry_t *cur = (key_entry_t*) key_entries->data; | ||
2396 | if (cur->id == id) | ||
2397 | return cur; | ||
2398 | key_entries = key_entries->link; | ||
2399 | } | ||
2400 | bb_error_msg_and_die("key %u is not defined", id); | ||
2401 | } | ||
2402 | #endif | ||
2281 | 2403 | ||
2282 | /* By doing init in a separate function we decrease stack usage | 2404 | /* By doing init in a separate function we decrease stack usage |
2283 | * in main loop. | 2405 | * in main loop. |
@@ -2286,6 +2408,10 @@ static NOINLINE void ntp_init(char **argv) | |||
2286 | { | 2408 | { |
2287 | unsigned opts; | 2409 | unsigned opts; |
2288 | llist_t *peers; | 2410 | llist_t *peers; |
2411 | #if ENABLE_FEATURE_NTP_AUTH | ||
2412 | llist_t *key_entries; | ||
2413 | char *key_file_path; | ||
2414 | #endif | ||
2289 | 2415 | ||
2290 | srand(getpid()); | 2416 | srand(getpid()); |
2291 | 2417 | ||
@@ -2302,8 +2428,10 @@ static NOINLINE void ntp_init(char **argv) | |||
2302 | 2428 | ||
2303 | /* Parse options */ | 2429 | /* Parse options */ |
2304 | peers = NULL; | 2430 | peers = NULL; |
2431 | IF_FEATURE_NTP_AUTH(key_entries = NULL;) | ||
2305 | opts = getopt32(argv, "^" | 2432 | opts = getopt32(argv, "^" |
2306 | "nqNx" /* compat */ | 2433 | "nqNx" /* compat */ |
2434 | IF_FEATURE_NTP_AUTH("k:") /* compat */ | ||
2307 | "wp:*S:"IF_FEATURE_NTPD_SERVER("l") /* NOT compat */ | 2435 | "wp:*S:"IF_FEATURE_NTPD_SERVER("l") /* NOT compat */ |
2308 | IF_FEATURE_NTPD_SERVER("I:") /* compat */ | 2436 | IF_FEATURE_NTPD_SERVER("I:") /* compat */ |
2309 | "d" /* compat */ | 2437 | "d" /* compat */ |
@@ -2311,11 +2439,11 @@ static NOINLINE void ntp_init(char **argv) | |||
2311 | "\0" | 2439 | "\0" |
2312 | "dd:wn" /* -d: counter; -p: list; -w implies -n */ | 2440 | "dd:wn" /* -d: counter; -p: list; -w implies -n */ |
2313 | IF_FEATURE_NTPD_SERVER(":Il") /* -I implies -l */ | 2441 | IF_FEATURE_NTPD_SERVER(":Il") /* -I implies -l */ |
2314 | , &peers, &G.script_name, | 2442 | IF_FEATURE_NTP_AUTH(, &key_file_path) |
2315 | #if ENABLE_FEATURE_NTPD_SERVER | 2443 | , &peers, &G.script_name |
2316 | &G.if_name, | 2444 | IF_FEATURE_NTPD_SERVER(, &G.if_name) |
2317 | #endif | 2445 | , &G.verbose |
2318 | &G.verbose); | 2446 | ); |
2319 | 2447 | ||
2320 | // if (opts & OPT_x) /* disable stepping, only slew is allowed */ | 2448 | // if (opts & OPT_x) /* disable stepping, only slew is allowed */ |
2321 | // G.time_was_stepped = 1; | 2449 | // G.time_was_stepped = 1; |
@@ -2341,19 +2469,108 @@ static NOINLINE void ntp_init(char **argv) | |||
2341 | logmode = LOGMODE_NONE; | 2469 | logmode = LOGMODE_NONE; |
2342 | } | 2470 | } |
2343 | 2471 | ||
2472 | #if ENABLE_FEATURE_NTP_AUTH | ||
2473 | if (opts & OPT_k) { | ||
2474 | char *tokens[4]; | ||
2475 | parser_t *parser; | ||
2476 | |||
2477 | parser = config_open(key_file_path); | ||
2478 | while (config_read(parser, tokens, 4, 3, "# \t", PARSE_NORMAL | PARSE_MIN_DIE) == 3) { | ||
2479 | key_entry_t *key_entry; | ||
2480 | char buffer[40]; | ||
2481 | smalluint hash_type; | ||
2482 | smalluint msg_size; | ||
2483 | smalluint key_length; | ||
2484 | char *key; | ||
2485 | |||
2486 | if ((tokens[1][0] | 0x20) == 'm') | ||
2487 | /* supports 'M' and 'md5' formats */ | ||
2488 | hash_type = HASH_MD5; | ||
2489 | else | ||
2490 | if (strncasecmp(tokens[1], "sha", 3) == 0) | ||
2491 | /* supports 'sha' and 'sha1' formats */ | ||
2492 | hash_type = HASH_SHA1; | ||
2493 | else | ||
2494 | bb_error_msg_and_die("only MD5 and SHA1 keys supported"); | ||
2495 | /* man ntp.keys: | ||
2496 | * MD5 The key is 1 to 16 printable characters terminated by an EOL, | ||
2497 | * whitespace, or a # (which is the "start of comment" character). | ||
2498 | * SHA | ||
2499 | * SHA1 | ||
2500 | * RMD160 The key is a hex-encoded ASCII string of 40 characters, which | ||
2501 | * is truncated as necessary. | ||
2502 | */ | ||
2503 | key_length = strnlen(tokens[2], sizeof(buffer)+1); | ||
2504 | if (key_length >= sizeof(buffer)+1) { | ||
2505 | err: | ||
2506 | bb_error_msg_and_die("malformed key at line %u", parser->lineno); | ||
2507 | } | ||
2508 | if (hash_type == HASH_MD5) { | ||
2509 | key = tokens[2]; | ||
2510 | msg_size = NTP_MSGSIZE_MD5_AUTH; | ||
2511 | } else /* it's hash_type == HASH_SHA1 */ | ||
2512 | if (!(key_length & 1)) { | ||
2513 | key_length >>= 1; | ||
2514 | if (!hex2bin(buffer, tokens[2], key_length)) | ||
2515 | goto err; | ||
2516 | key = buffer; | ||
2517 | msg_size = NTP_MSGSIZE_SHA1_AUTH; | ||
2518 | } else { | ||
2519 | goto err; | ||
2520 | } | ||
2521 | key_entry = xzalloc(sizeof(*key_entry) + key_length); | ||
2522 | key_entry->type = hash_type; | ||
2523 | key_entry->msg_size = msg_size; | ||
2524 | key_entry->key_length = key_length; | ||
2525 | memcpy(key_entry->key, key, key_length); | ||
2526 | key_entry->id = xatou_range(tokens[0], 1, MAX_KEY_NUMBER); | ||
2527 | llist_add_to(&key_entries, key_entry); | ||
2528 | } | ||
2529 | config_close(parser); | ||
2530 | } | ||
2531 | #endif | ||
2344 | if (peers) { | 2532 | if (peers) { |
2533 | #if ENABLE_FEATURE_NTP_AUTH | ||
2534 | while (peers) { | ||
2535 | char *peer = llist_pop(&peers); | ||
2536 | key_entry_t *key_entry = NULL; | ||
2537 | if (strncmp(peer, "keyno:", 6) == 0) { | ||
2538 | char *end; | ||
2539 | int key_id; | ||
2540 | peer += 6; | ||
2541 | end = strchr(peer, ':'); | ||
2542 | if (!end) bb_show_usage(); | ||
2543 | *end = '\0'; | ||
2544 | key_id = xatou_range(peer, 1, MAX_KEY_NUMBER); | ||
2545 | *end = ':'; | ||
2546 | key_entry = find_key_entry(key_entries, key_id); | ||
2547 | peer = end + 1; | ||
2548 | } | ||
2549 | add_peers(peer, key_entry); | ||
2550 | } | ||
2551 | #else | ||
2345 | while (peers) | 2552 | while (peers) |
2346 | add_peers(llist_pop(&peers)); | 2553 | add_peers(llist_pop(&peers), NULL); |
2554 | #endif | ||
2347 | } | 2555 | } |
2348 | #if ENABLE_FEATURE_NTPD_CONF | 2556 | #if ENABLE_FEATURE_NTPD_CONF |
2349 | else { | 2557 | else { |
2350 | parser_t *parser; | 2558 | parser_t *parser; |
2351 | char *token[3]; | 2559 | char *token[3 + 2*ENABLE_FEATURE_NTP_AUTH]; |
2352 | 2560 | ||
2353 | parser = config_open("/etc/ntp.conf"); | 2561 | parser = config_open("/etc/ntp.conf"); |
2354 | while (config_read(parser, token, 3, 1, "# \t", PARSE_NORMAL)) { | 2562 | while (config_read(parser, token, 3 + 2*ENABLE_FEATURE_NTP_AUTH, 1, "# \t", PARSE_NORMAL)) { |
2355 | if (strcmp(token[0], "server") == 0 && token[1]) { | 2563 | if (strcmp(token[0], "server") == 0 && token[1]) { |
2356 | add_peers(token[1]); | 2564 | # if ENABLE_FEATURE_NTP_AUTH |
2565 | key_entry_t *key_entry = NULL; | ||
2566 | if (token[2] && token[3] && strcmp(token[2], "key") == 0) { | ||
2567 | unsigned key_id = xatou_range(token[3], 1, MAX_KEY_NUMBER); | ||
2568 | key_entry = find_key_entry(key_entries, key_id); | ||
2569 | } | ||
2570 | add_peers(token[1], key_entry); | ||
2571 | # else | ||
2572 | add_peers(token[1], NULL); | ||
2573 | # endif | ||
2357 | continue; | 2574 | continue; |
2358 | } | 2575 | } |
2359 | bb_error_msg("skipping %s:%u: unimplemented command '%s'", | 2576 | bb_error_msg("skipping %s:%u: unimplemented command '%s'", |
@@ -2394,6 +2611,7 @@ static NOINLINE void ntp_init(char **argv) | |||
2394 | | (1 << SIGCHLD) | 2611 | | (1 << SIGCHLD) |
2395 | , SIG_IGN | 2612 | , SIG_IGN |
2396 | ); | 2613 | ); |
2614 | //TODO: free unused elements of key_entries? | ||
2397 | } | 2615 | } |
2398 | 2616 | ||
2399 | int ntpd_main(int argc UNUSED_PARAM, char **argv) MAIN_EXTERNALLY_VISIBLE; | 2617 | int ntpd_main(int argc UNUSED_PARAM, char **argv) MAIN_EXTERNALLY_VISIBLE; |
diff --git a/networking/tls.c b/networking/tls.c index fce1d0ea6..38eb79798 100644 --- a/networking/tls.c +++ b/networking/tls.c | |||
@@ -12,16 +12,18 @@ | |||
12 | //kbuild:lib-$(CONFIG_TLS) += tls_pstm_montgomery_reduce.o | 12 | //kbuild:lib-$(CONFIG_TLS) += tls_pstm_montgomery_reduce.o |
13 | //kbuild:lib-$(CONFIG_TLS) += tls_pstm_mul_comba.o | 13 | //kbuild:lib-$(CONFIG_TLS) += tls_pstm_mul_comba.o |
14 | //kbuild:lib-$(CONFIG_TLS) += tls_pstm_sqr_comba.o | 14 | //kbuild:lib-$(CONFIG_TLS) += tls_pstm_sqr_comba.o |
15 | //kbuild:lib-$(CONFIG_TLS) += tls_rsa.o | ||
16 | //kbuild:lib-$(CONFIG_TLS) += tls_aes.o | 15 | //kbuild:lib-$(CONFIG_TLS) += tls_aes.o |
17 | ////kbuild:lib-$(CONFIG_TLS) += tls_aes_gcm.o | 16 | //kbuild:lib-$(CONFIG_TLS) += tls_aesgcm.o |
17 | //kbuild:lib-$(CONFIG_TLS) += tls_rsa.o | ||
18 | //kbuild:lib-$(CONFIG_TLS) += tls_fe.o | ||
18 | 19 | ||
19 | #include "tls.h" | 20 | #include "tls.h" |
20 | 21 | ||
22 | // works against "openssl s_server -cipher NULL" | ||
23 | // and against wolfssl-3.9.10-stable/examples/server/server.c: | ||
24 | #define ALLOW_RSA_NULL_SHA256 0 // for testing (does everything except encrypting) | ||
25 | |||
21 | //Tested against kernel.org: | 26 | //Tested against kernel.org: |
22 | //TLS 1.2 | ||
23 | #define TLS_MAJ 3 | ||
24 | #define TLS_MIN 3 | ||
25 | //#define CIPHER_ID TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA // ok, recvs SERVER_KEY_EXCHANGE *** matrixssl uses this on my box | 27 | //#define CIPHER_ID TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA // ok, recvs SERVER_KEY_EXCHANGE *** matrixssl uses this on my box |
26 | //#define CIPHER_ID TLS_RSA_WITH_AES_256_CBC_SHA256 // ok, no SERVER_KEY_EXCHANGE | 28 | //#define CIPHER_ID TLS_RSA_WITH_AES_256_CBC_SHA256 // ok, no SERVER_KEY_EXCHANGE |
27 | //#define CIPHER_ID TLS_DH_anon_WITH_AES_256_CBC_SHA // SSL_ALERT_HANDSHAKE_FAILURE | 29 | //#define CIPHER_ID TLS_DH_anon_WITH_AES_256_CBC_SHA // SSL_ALERT_HANDSHAKE_FAILURE |
@@ -35,26 +37,28 @@ | |||
35 | //#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 | 37 | //#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 |
36 | //#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 // SSL_ALERT_HANDSHAKE_FAILURE | 38 | //#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 // SSL_ALERT_HANDSHAKE_FAILURE |
37 | //#define CIPHER_ID TLS_RSA_WITH_AES_256_GCM_SHA384 // ok, no SERVER_KEY_EXCHANGE | 39 | //#define CIPHER_ID TLS_RSA_WITH_AES_256_GCM_SHA384 // ok, no SERVER_KEY_EXCHANGE |
38 | //#define CIPHER_ID TLS_RSA_WITH_AES_128_GCM_SHA256 // ok, no SERVER_KEY_EXCHANGE *** select this? | 40 | //#define CIPHER_ID TLS_RSA_WITH_AES_128_GCM_SHA256 // ok, no SERVER_KEY_EXCHANGE |
39 | |||
40 | // works against "openssl s_server -cipher NULL" | ||
41 | // and against wolfssl-3.9.10-stable/examples/server/server.c: | ||
42 | //#define CIPHER_ID1 TLS_RSA_WITH_NULL_SHA256 // for testing (does everything except encrypting) | ||
43 | 41 | ||
44 | // works against wolfssl-3.9.10-stable/examples/server/server.c | 42 | // works against wolfssl-3.9.10-stable/examples/server/server.c |
45 | // works for kernel.org | 43 | // works for kernel.org |
46 | // does not work for cdn.kernel.org (e.g. downloading an actual tarball, not a web page) | 44 | // does not work for cdn.kernel.org (e.g. downloading an actual tarball, not a web page) |
47 | // getting alert 40 "handshake failure" at once | 45 | // getting alert 40 "handshake failure" at once |
48 | // with GNU Wget 1.18, they agree on TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xC02F) cipher | 46 | // with GNU Wget 1.18, they agree on TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xC02F) cipher |
49 | // fail: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES256-SHA256 | 47 | // fail: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -cipher AES256-SHA256 |
50 | // fail: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES256-GCM-SHA384 | 48 | // fail: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -cipher AES256-GCM-SHA384 |
51 | // fail: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES128-SHA256 | 49 | // fail: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -cipher AES128-SHA256 |
52 | // ok: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES128-GCM-SHA256 | 50 | // ok: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -cipher AES128-GCM-SHA256 |
53 | // ok: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES128-SHA | 51 | // ok: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -cipher AES128-SHA |
54 | // (TLS_RSA_WITH_AES_128_CBC_SHA - in TLS 1.2 it's mandated to be always supported) | 52 | // (TLS_RSA_WITH_AES_128_CBC_SHA - in TLS 1.2 it's mandated to be always supported) |
55 | #define CIPHER_ID1 TLS_RSA_WITH_AES_256_CBC_SHA256 // no SERVER_KEY_EXCHANGE from peer | 53 | //#define CIPHER_ID1 TLS_RSA_WITH_AES_256_CBC_SHA256 //0x003D |
56 | // Works with "wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.9.5.tar.xz" | 54 | // Works with "wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.9.5.tar.xz" |
57 | #define CIPHER_ID2 TLS_RSA_WITH_AES_128_CBC_SHA | 55 | //#define CIPHER_ID2 TLS_RSA_WITH_AES_128_CBC_SHA //0x002F |
56 | |||
57 | // bug #11456: | ||
58 | // ftp.openbsd.org only supports ECDHE-RSA-AESnnn-GCM-SHAnnn or ECDHE-RSA-CHACHA20-POLY1305 | ||
59 | //#define CIPHER_ID3 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 //0xC02F | ||
60 | // host is.gd accepts only ECDHE-ECDSA-foo (the simplest which works: ECDHE-ECDSA-AES128-SHA 0xC009) | ||
61 | //#define CIPHER_ID4 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA //0xC009 | ||
58 | 62 | ||
59 | 63 | ||
60 | #define TLS_DEBUG 0 | 64 | #define TLS_DEBUG 0 |
@@ -84,6 +88,11 @@ | |||
84 | # define dbg_der(...) ((void)0) | 88 | # define dbg_der(...) ((void)0) |
85 | #endif | 89 | #endif |
86 | 90 | ||
91 | |||
92 | //TLS 1.2 | ||
93 | #define TLS_MAJ 3 | ||
94 | #define TLS_MIN 3 | ||
95 | |||
87 | #define RECORD_TYPE_CHANGE_CIPHER_SPEC 20 /* 0x14 */ | 96 | #define RECORD_TYPE_CHANGE_CIPHER_SPEC 20 /* 0x14 */ |
88 | #define RECORD_TYPE_ALERT 21 /* 0x15 */ | 97 | #define RECORD_TYPE_ALERT 21 /* 0x15 */ |
89 | #define RECORD_TYPE_HANDSHAKE 22 /* 0x16 */ | 98 | #define RECORD_TYPE_HANDSHAKE 22 /* 0x16 */ |
@@ -102,66 +111,98 @@ | |||
102 | #define HANDSHAKE_CLIENT_KEY_EXCHANGE 16 /* 0x10 */ | 111 | #define HANDSHAKE_CLIENT_KEY_EXCHANGE 16 /* 0x10 */ |
103 | #define HANDSHAKE_FINISHED 20 /* 0x14 */ | 112 | #define HANDSHAKE_FINISHED 20 /* 0x14 */ |
104 | 113 | ||
114 | #define TLS_EMPTY_RENEGOTIATION_INFO_SCSV 0x00FF /* not a real cipher id... */ | ||
115 | |||
105 | #define SSL_NULL_WITH_NULL_NULL 0x0000 | 116 | #define SSL_NULL_WITH_NULL_NULL 0x0000 |
106 | #define SSL_RSA_WITH_NULL_MD5 0x0001 | 117 | #define SSL_RSA_WITH_NULL_MD5 0x0001 |
107 | #define SSL_RSA_WITH_NULL_SHA 0x0002 | 118 | #define SSL_RSA_WITH_NULL_SHA 0x0002 |
108 | #define SSL_RSA_WITH_RC4_128_MD5 0x0004 | 119 | #define SSL_RSA_WITH_RC4_128_MD5 0x0004 |
109 | #define SSL_RSA_WITH_RC4_128_SHA 0x0005 | 120 | #define SSL_RSA_WITH_RC4_128_SHA 0x0005 |
121 | #define TLS_RSA_WITH_IDEA_CBC_SHA 0x0007 /* 7 */ | ||
110 | #define SSL_RSA_WITH_3DES_EDE_CBC_SHA 0x000A /* 10 */ | 122 | #define SSL_RSA_WITH_3DES_EDE_CBC_SHA 0x000A /* 10 */ |
111 | #define TLS_RSA_WITH_AES_128_CBC_SHA 0x002F /* 47 */ | ||
112 | #define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035 /* 53 */ | ||
113 | #define TLS_RSA_WITH_NULL_SHA256 0x003B /* 59 */ | ||
114 | |||
115 | #define TLS_EMPTY_RENEGOTIATION_INFO_SCSV 0x00FF | ||
116 | 123 | ||
117 | #define TLS_RSA_WITH_IDEA_CBC_SHA 0x0007 /* 7 */ | ||
118 | #define SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x0016 /* 22 */ | 124 | #define SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x0016 /* 22 */ |
119 | #define SSL_DH_anon_WITH_RC4_128_MD5 0x0018 /* 24 */ | 125 | #define SSL_DH_anon_WITH_RC4_128_MD5 0x0018 /* 24 */ |
120 | #define SSL_DH_anon_WITH_3DES_EDE_CBC_SHA 0x001B /* 27 */ | 126 | #define SSL_DH_anon_WITH_3DES_EDE_CBC_SHA 0x001B /* 27 */ |
127 | #define TLS_RSA_WITH_AES_128_CBC_SHA 0x002F /*SSLv3 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1 */ | ||
121 | #define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x0033 /* 51 */ | 128 | #define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x0033 /* 51 */ |
122 | #define TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x0039 /* 57 */ | ||
123 | #define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x0067 /* 103 */ | ||
124 | #define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x006B /* 107 */ | ||
125 | #define TLS_DH_anon_WITH_AES_128_CBC_SHA 0x0034 /* 52 */ | 129 | #define TLS_DH_anon_WITH_AES_128_CBC_SHA 0x0034 /* 52 */ |
130 | #define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035 /* 53 */ | ||
131 | #define TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x0039 /* 57 */ | ||
126 | #define TLS_DH_anon_WITH_AES_256_CBC_SHA 0x003A /* 58 */ | 132 | #define TLS_DH_anon_WITH_AES_256_CBC_SHA 0x003A /* 58 */ |
133 | #define TLS_RSA_WITH_NULL_SHA256 0x003B /* 59 */ | ||
127 | #define TLS_RSA_WITH_AES_128_CBC_SHA256 0x003C /* 60 */ | 134 | #define TLS_RSA_WITH_AES_128_CBC_SHA256 0x003C /* 60 */ |
128 | #define TLS_RSA_WITH_AES_256_CBC_SHA256 0x003D /* 61 */ | 135 | #define TLS_RSA_WITH_AES_256_CBC_SHA256 0x003D /* 61 */ |
129 | #define TLS_RSA_WITH_SEED_CBC_SHA 0x0096 /* 150 */ | 136 | #define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x0067 /* 103 */ |
137 | #define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x006B /* 107 */ | ||
130 | #define TLS_PSK_WITH_AES_128_CBC_SHA 0x008C /* 140 */ | 138 | #define TLS_PSK_WITH_AES_128_CBC_SHA 0x008C /* 140 */ |
131 | #define TLS_PSK_WITH_AES_128_CBC_SHA256 0x00AE /* 174 */ | ||
132 | #define TLS_PSK_WITH_AES_256_CBC_SHA384 0x00AF /* 175 */ | ||
133 | #define TLS_PSK_WITH_AES_256_CBC_SHA 0x008D /* 141 */ | 139 | #define TLS_PSK_WITH_AES_256_CBC_SHA 0x008D /* 141 */ |
134 | #define TLS_DHE_PSK_WITH_AES_128_CBC_SHA 0x0090 /* 144 */ | 140 | #define TLS_DHE_PSK_WITH_AES_128_CBC_SHA 0x0090 /* 144 */ |
135 | #define TLS_DHE_PSK_WITH_AES_256_CBC_SHA 0x0091 /* 145 */ | 141 | #define TLS_DHE_PSK_WITH_AES_256_CBC_SHA 0x0091 /* 145 */ |
142 | #define TLS_RSA_WITH_SEED_CBC_SHA 0x0096 /* 150 */ | ||
143 | #define TLS_RSA_WITH_AES_128_GCM_SHA256 0x009C /*TLSv1.2 Kx=RSA Au=RSA Enc=AESGCM(128) Mac=AEAD */ | ||
144 | #define TLS_RSA_WITH_AES_256_GCM_SHA384 0x009D /*TLSv1.2 Kx=RSA Au=RSA Enc=AESGCM(256) Mac=AEAD */ | ||
145 | #define TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x009E /*TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(128) Mac=AEAD */ | ||
146 | #define TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x009F /*TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(256) Mac=AEAD */ | ||
147 | #define TLS_DH_anon_WITH_AES_128_GCM_SHA256 0x00A6 /* RFC 5288 */ | ||
148 | #define TLS_DH_anon_WITH_AES_256_GCM_SHA384 0x00A7 /* RFC 5288 */ | ||
149 | #define TLS_PSK_WITH_AES_128_CBC_SHA256 0x00AE /* 174 */ | ||
150 | #define TLS_PSK_WITH_AES_256_CBC_SHA384 0x00AF /* 175 */ | ||
136 | #define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 /* 49156 */ | 151 | #define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 /* 49156 */ |
137 | #define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 /* 49157 */ | 152 | #define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 /* 49157 */ |
138 | #define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 /* 49161 */ | 153 | #define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 /*TLSv1 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA1 */ |
139 | #define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A /* 49162 */ | 154 | #define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A /*TLSv1 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA1 */ |
140 | #define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 /* 49170 */ | ||
141 | #define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 /* 49171 */ | ||
142 | #define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 /* 49172 */ | ||
143 | #define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E /* 49166 */ | 155 | #define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E /* 49166 */ |
144 | #define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F /* 49167 */ | 156 | #define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F /* 49167 */ |
145 | #define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 /* 49187 */ | 157 | #define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 /* 49170 */ |
146 | #define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 /* 49188 */ | 158 | #define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 /*TLSv1 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA1 */ |
159 | #define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 /*TLSv1 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA1 */ | ||
160 | #define TLS_ECDH_anon_WITH_AES_128_CBC_SHA 0xC018 /* RFC 4492 */ | ||
161 | #define TLS_ECDH_anon_WITH_AES_256_CBC_SHA 0xC019 /* RFC 4492 */ | ||
162 | #define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 /*TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA256 */ | ||
163 | #define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 /*TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA384 */ | ||
147 | #define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 /* 49189 */ | 164 | #define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 /* 49189 */ |
148 | #define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 /* 49190 */ | 165 | #define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 /* 49190 */ |
149 | #define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 /* 49191 */ | 166 | #define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 /*TLSv1.2 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA256 */ |
150 | #define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 /* 49192 */ | 167 | #define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 /*TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384 */ |
151 | #define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 /* 49193 */ | 168 | #define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 /* 49193 */ |
152 | #define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A /* 49194 */ | 169 | #define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A /* 49194 */ |
153 | |||
154 | /* RFC 5288 "AES Galois Counter Mode (GCM) Cipher Suites for TLS" */ | 170 | /* RFC 5288 "AES Galois Counter Mode (GCM) Cipher Suites for TLS" */ |
155 | #define TLS_RSA_WITH_AES_128_GCM_SHA256 0x009C /* 156 */ | 171 | #define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B /*TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD */ |
156 | #define TLS_RSA_WITH_AES_256_GCM_SHA384 0x009D /* 157 */ | 172 | #define TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C /*TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD */ |
157 | #define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B /* 49195 */ | ||
158 | #define TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C /* 49196 */ | ||
159 | #define TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D /* 49197 */ | 173 | #define TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D /* 49197 */ |
160 | #define TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E /* 49198 */ | 174 | #define TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E /* 49198 */ |
161 | #define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F /* 49199 */ | 175 | #define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F /*TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD */ |
162 | #define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 /* 49200 */ | 176 | #define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 /*TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD */ |
163 | #define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 /* 49201 */ | 177 | #define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 /* 49201 */ |
164 | #define TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 /* 49202 */ | 178 | #define TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 /* 49202 */ |
179 | #define TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA 0xC035 | ||
180 | #define TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA 0xC036 | ||
181 | #define TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 0xC037 | ||
182 | #define TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 0xC038 | ||
183 | |||
184 | /* From http://wiki.mozilla.org/Security/Server_Side_TLS */ | ||
185 | /* and 'openssl ciphers -V -stdname' */ | ||
186 | #define TLS_RSA_WITH_AES_128_CCM 0xC09C /*TLSv1.2 Kx=RSA Au=RSA Enc=AESCCM(128) Mac=AEAD */ | ||
187 | #define TLS_RSA_WITH_AES_256_CCM 0xC09D /*TLSv1.2 Kx=RSA Au=RSA Enc=AESCCM(256) Mac=AEAD */ | ||
188 | #define TLS_DHE_RSA_WITH_AES_128_CCM 0xC09E /*TLSv1.2 Kx=DH Au=RSA Enc=AESCCM(128) Mac=AEAD */ | ||
189 | #define TLS_DHE_RSA_WITH_AES_256_CCM 0xC09F /*TLSv1.2 Kx=DH Au=RSA Enc=AESCCM(256) Mac=AEAD */ | ||
190 | #define TLS_RSA_WITH_AES_128_CCM_8 0xC0A0 /*TLSv1.2 Kx=RSA Au=RSA Enc=AESCCM8(128) Mac=AEAD */ | ||
191 | #define TLS_RSA_WITH_AES_256_CCM_8 0xC0A1 /*TLSv1.2 Kx=RSA Au=RSA Enc=AESCCM8(256) Mac=AEAD */ | ||
192 | #define TLS_DHE_RSA_WITH_AES_128_CCM_8 0xC0A2 /*TLSv1.2 Kx=DH Au=RSA Enc=AESCCM8(128) Mac=AEAD */ | ||
193 | #define TLS_DHE_RSA_WITH_AES_256_CCM_8 0xC0A3 /*TLSv1.2 Kx=DH Au=RSA Enc=AESCCM8(256) Mac=AEAD */ | ||
194 | #define TLS_ECDHE_ECDSA_WITH_AES_128_CCM 0xC0AC /*TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESCCM(128) Mac=AEAD */ | ||
195 | #define TLS_ECDHE_ECDSA_WITH_AES_256_CCM 0xC0AD /*TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESCCM(256) Mac=AEAD */ | ||
196 | #define TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE /*TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESCCM8(128) Mac=AEAD */ | ||
197 | #define TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF /*TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESCCM8(256) Mac=AEAD */ | ||
198 | #define TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8 /*TLSv1.2 Kx=ECDH Au=RSA Enc=CHACHA20/POLY1305(256) Mac=AEAD */ | ||
199 | #define TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9 /*TLSv1.2 Kx=ECDH Au=ECDSA Enc=CHACHA20/POLY1305(256) Mac=AEAD */ | ||
200 | #define TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCAA /*TLSv1.2 Kx=DH Au=RSA Enc=CHACHA20/POLY1305(256) Mac=AEAD */ | ||
201 | |||
202 | #define TLS_AES_128_GCM_SHA256 0x1301 /*TLSv1.3 Kx=any Au=any Enc=AESGCM(128) Mac=AEAD */ | ||
203 | #define TLS_AES_256_GCM_SHA384 0x1302 /*TLSv1.3 Kx=any Au=any Enc=AESGCM(256) Mac=AEAD */ | ||
204 | #define TLS_CHACHA20_POLY1305_SHA256 0x1303 /*TLSv1.3 Kx=any Au=any Enc=CHACHA20/POLY1305(256) Mac=AEAD */ | ||
205 | #define TLS_AES_128_CCM_SHA256 0x1304 /*TLSv1.3 Kx=any Au=any Enc=AESCCM(128) Mac=AEAD */ | ||
165 | 206 | ||
166 | /* Might go to libbb.h */ | 207 | /* Might go to libbb.h */ |
167 | #define TLS_MAX_CRYPTBLOCK_SIZE 16 | 208 | #define TLS_MAX_CRYPTBLOCK_SIZE 16 |
@@ -172,7 +213,6 @@ enum { | |||
172 | SHA1_OUTSIZE = 20, | 213 | SHA1_OUTSIZE = 20, |
173 | SHA256_OUTSIZE = 32, | 214 | SHA256_OUTSIZE = 32, |
174 | 215 | ||
175 | AES_BLOCKSIZE = 16, | ||
176 | AES128_KEYSIZE = 16, | 216 | AES128_KEYSIZE = 16, |
177 | AES256_KEYSIZE = 32, | 217 | AES256_KEYSIZE = 32, |
178 | 218 | ||
@@ -181,10 +221,10 @@ enum { | |||
181 | RECHDR_LEN = 5, | 221 | RECHDR_LEN = 5, |
182 | 222 | ||
183 | /* 8 = 3+5. 3 extra bytes result in record data being 32-bit aligned */ | 223 | /* 8 = 3+5. 3 extra bytes result in record data being 32-bit aligned */ |
184 | OUTBUF_PFX = 8 + AES_BLOCKSIZE, /* header + IV */ | 224 | OUTBUF_PFX = 8 + AES_BLOCK_SIZE, /* header + IV */ |
185 | OUTBUF_SFX = TLS_MAX_MAC_SIZE + TLS_MAX_CRYPTBLOCK_SIZE, /* MAC + padding */ | 225 | OUTBUF_SFX = TLS_MAX_MAC_SIZE + TLS_MAX_CRYPTBLOCK_SIZE, /* MAC + padding */ |
186 | 226 | ||
187 | // RFC 5246 | 227 | // RFC 5246: |
188 | // | 6.2.1. Fragmentation | 228 | // | 6.2.1. Fragmentation |
189 | // | The record layer fragments information blocks into TLSPlaintext | 229 | // | The record layer fragments information blocks into TLSPlaintext |
190 | // | records carrying data in chunks of 2^14 bytes or less. Client | 230 | // | records carrying data in chunks of 2^14 bytes or less. Client |
@@ -219,6 +259,14 @@ enum { | |||
219 | // | The length (in bytes) of the following TLSCiphertext.fragment. | 259 | // | The length (in bytes) of the following TLSCiphertext.fragment. |
220 | // | The length MUST NOT exceed 2^14 + 2048. | 260 | // | The length MUST NOT exceed 2^14 + 2048. |
221 | MAX_INBUF = RECHDR_LEN + (1 << 14) + 2048, | 261 | MAX_INBUF = RECHDR_LEN + (1 << 14) + 2048, |
262 | |||
263 | /* Bits for tls->flags */ | ||
264 | NEED_EC_KEY = 1 << 0, | ||
265 | GOT_CERT_RSA_KEY_ALG = 1 << 1, | ||
266 | GOT_CERT_ECDSA_KEY_ALG = 1 << 2, // so far unused | ||
267 | GOT_EC_KEY = 1 << 3, | ||
268 | ENCRYPTION_AESGCM = 1 << 4, // else AES-SHA (or NULL-SHA if ALLOW_RSA_NULL_SHA256=1) | ||
269 | ENCRYPT_ON_WRITE = 1 << 5, | ||
222 | }; | 270 | }; |
223 | 271 | ||
224 | struct record_hdr { | 272 | struct record_hdr { |
@@ -233,12 +281,15 @@ struct tls_handshake_data { | |||
233 | 281 | ||
234 | uint8_t client_and_server_rand32[2 * 32]; | 282 | uint8_t client_and_server_rand32[2 * 32]; |
235 | uint8_t master_secret[48]; | 283 | uint8_t master_secret[48]; |
284 | |||
236 | //TODO: store just the DER key here, parse/use/delete it when sending client key | 285 | //TODO: store just the DER key here, parse/use/delete it when sending client key |
237 | //this way it will stay key type agnostic here. | 286 | //this way it will stay key type agnostic here. |
238 | psRsaKey_t server_rsa_pub_key; | 287 | psRsaKey_t server_rsa_pub_key; |
288 | uint8_t ecc_pub_key32[32]; | ||
239 | 289 | ||
240 | unsigned saved_client_hello_size; | 290 | /* HANDSHAKE HASH: */ |
241 | uint8_t saved_client_hello[1]; | 291 | //unsigned saved_client_hello_size; |
292 | //uint8_t saved_client_hello[1]; | ||
242 | }; | 293 | }; |
243 | 294 | ||
244 | 295 | ||
@@ -248,6 +299,15 @@ static unsigned get24be(const uint8_t *p) | |||
248 | } | 299 | } |
249 | 300 | ||
250 | #if TLS_DEBUG | 301 | #if TLS_DEBUG |
302 | /* Nondestructively see the current hash value */ | ||
303 | # if TLS_DEBUG_HASH | ||
304 | static unsigned sha_peek(md5sha_ctx_t *ctx, void *buffer) | ||
305 | { | ||
306 | md5sha_ctx_t ctx_copy = *ctx; /* struct copy */ | ||
307 | return sha_end(&ctx_copy, buffer); | ||
308 | } | ||
309 | # endif | ||
310 | |||
251 | static void dump_hex(const char *fmt, const void *vp, int len) | 311 | static void dump_hex(const char *fmt, const void *vp, int len) |
252 | { | 312 | { |
253 | char hexbuf[32 * 1024 + 4]; | 313 | char hexbuf[32 * 1024 + 4]; |
@@ -287,7 +347,7 @@ static void dump_tls_record(const void *vp, int len) | |||
287 | # define dump_tls_record(...) ((void)0) | 347 | # define dump_tls_record(...) ((void)0) |
288 | #endif | 348 | #endif |
289 | 349 | ||
290 | void tls_get_random(void *buf, unsigned len) | 350 | void FAST_FUNC tls_get_random(void *buf, unsigned len) |
291 | { | 351 | { |
292 | #if !ENABLE_PLATFORM_MINGW32 | 352 | #if !ENABLE_PLATFORM_MINGW32 |
293 | if (len != open_read_close("/dev/urandom", buf, len)) | 353 | if (len != open_read_close("/dev/urandom", buf, len)) |
@@ -299,16 +359,32 @@ void tls_get_random(void *buf, unsigned len) | |||
299 | #endif | 359 | #endif |
300 | } | 360 | } |
301 | 361 | ||
302 | /* Nondestructively see the current hash value */ | 362 | static void xorbuf3(void *dst, const void *src1, const void *src2, unsigned count) |
303 | static unsigned sha_peek(md5sha_ctx_t *ctx, void *buffer) | ||
304 | { | 363 | { |
305 | md5sha_ctx_t ctx_copy = *ctx; /* struct copy */ | 364 | uint8_t *d = dst; |
306 | return sha_end(&ctx_copy, buffer); | 365 | const uint8_t *s1 = src1; |
366 | const uint8_t* s2 = src2; | ||
367 | while (count--) | ||
368 | *d++ = *s1++ ^ *s2++; | ||
307 | } | 369 | } |
308 | 370 | ||
309 | static ALWAYS_INLINE unsigned get_handshake_hash(tls_state_t *tls, void *buffer) | 371 | void FAST_FUNC xorbuf(void *dst, const void *src, unsigned count) |
310 | { | 372 | { |
311 | return sha_peek(&tls->hsd->handshake_hash_ctx, buffer); | 373 | xorbuf3(dst, dst, src, count); |
374 | } | ||
375 | |||
376 | void FAST_FUNC xorbuf_aligned_AES_BLOCK_SIZE(void *dst, const void *src) | ||
377 | { | ||
378 | unsigned long *d = dst; | ||
379 | const unsigned long *s = src; | ||
380 | d[0] ^= s[0]; | ||
381 | #if ULONG_MAX <= 0xffffffffffffffff | ||
382 | d[1] ^= s[1]; | ||
383 | #if ULONG_MAX == 0xffffffff | ||
384 | d[2] ^= s[2]; | ||
385 | d[3] ^= s[3]; | ||
386 | #endif | ||
387 | #endif | ||
312 | } | 388 | } |
313 | 389 | ||
314 | #if !TLS_DEBUG_HASH | 390 | #if !TLS_DEBUG_HASH |
@@ -335,7 +411,7 @@ static void hash_handshake(tls_state_t *tls, const char *fmt, const void *buffer | |||
335 | #endif | 411 | #endif |
336 | } | 412 | } |
337 | 413 | ||
338 | // RFC 2104 | 414 | // RFC 2104: |
339 | // HMAC(key, text) based on a hash H (say, sha256) is: | 415 | // HMAC(key, text) based on a hash H (say, sha256) is: |
340 | // ipad = [0x36 x INSIZE] | 416 | // ipad = [0x36 x INSIZE] |
341 | // opad = [0x5c x INSIZE] | 417 | // opad = [0x5c x INSIZE] |
@@ -350,35 +426,12 @@ typedef struct hmac_precomputed { | |||
350 | md5sha_ctx_t hashed_key_xor_opad; | 426 | md5sha_ctx_t hashed_key_xor_opad; |
351 | } hmac_precomputed_t; | 427 | } hmac_precomputed_t; |
352 | 428 | ||
353 | static unsigned hmac_sha_precomputed_v( | ||
354 | hmac_precomputed_t *pre, | ||
355 | uint8_t *out, | ||
356 | va_list va) | ||
357 | { | ||
358 | uint8_t *text; | ||
359 | unsigned len; | ||
360 | |||
361 | /* pre->hashed_key_xor_ipad contains unclosed "H((key XOR ipad) +" state */ | ||
362 | /* pre->hashed_key_xor_opad contains unclosed "H((key XOR opad) +" state */ | ||
363 | |||
364 | /* calculate out = H((key XOR ipad) + text) */ | ||
365 | while ((text = va_arg(va, uint8_t*)) != NULL) { | ||
366 | unsigned text_size = va_arg(va, unsigned); | ||
367 | md5sha_hash(&pre->hashed_key_xor_ipad, text, text_size); | ||
368 | } | ||
369 | len = sha_end(&pre->hashed_key_xor_ipad, out); | ||
370 | |||
371 | /* out = H((key XOR opad) + out) */ | ||
372 | md5sha_hash(&pre->hashed_key_xor_opad, out, len); | ||
373 | return sha_end(&pre->hashed_key_xor_opad, out); | ||
374 | } | ||
375 | |||
376 | typedef void md5sha_begin_func(md5sha_ctx_t *ctx) FAST_FUNC; | 429 | typedef void md5sha_begin_func(md5sha_ctx_t *ctx) FAST_FUNC; |
377 | static void hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size, md5sha_begin_func *begin) | 430 | static void hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size, md5sha_begin_func *begin) |
378 | { | 431 | { |
379 | uint8_t key_xor_ipad[SHA_INSIZE]; | 432 | uint8_t key_xor_ipad[SHA_INSIZE]; |
380 | uint8_t key_xor_opad[SHA_INSIZE]; | 433 | uint8_t key_xor_opad[SHA_INSIZE]; |
381 | uint8_t tempkey[SHA1_OUTSIZE < SHA256_OUTSIZE ? SHA256_OUTSIZE : SHA1_OUTSIZE]; | 434 | // uint8_t tempkey[SHA1_OUTSIZE < SHA256_OUTSIZE ? SHA256_OUTSIZE : SHA1_OUTSIZE]; |
382 | unsigned i; | 435 | unsigned i; |
383 | 436 | ||
384 | // "The authentication key can be of any length up to INSIZE, the | 437 | // "The authentication key can be of any length up to INSIZE, the |
@@ -386,10 +439,18 @@ static void hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size, | |||
386 | // than INSIZE bytes will first hash the key using H and then use the | 439 | // than INSIZE bytes will first hash the key using H and then use the |
387 | // resultant OUTSIZE byte string as the actual key to HMAC." | 440 | // resultant OUTSIZE byte string as the actual key to HMAC." |
388 | if (key_size > SHA_INSIZE) { | 441 | if (key_size > SHA_INSIZE) { |
389 | md5sha_ctx_t ctx; | 442 | bb_error_msg_and_die("HMAC key>64"); //does not happen (yet?) |
390 | begin(&ctx); | 443 | // md5sha_ctx_t ctx; |
391 | md5sha_hash(&ctx, key, key_size); | 444 | // begin(&ctx); |
392 | key_size = sha_end(&ctx, tempkey); | 445 | // md5sha_hash(&ctx, key, key_size); |
446 | // key_size = sha_end(&ctx, tempkey); | ||
447 | // //key = tempkey; - right? RIGHT? why does it work without this? | ||
448 | // // because SHA_INSIZE is 64, but hmac() is always called with | ||
449 | // // key_size = tls->MAC_size = SHA1/256_OUTSIZE (20 or 32), | ||
450 | // // and prf_hmac_sha256() -> hmac_sha256() key sizes are: | ||
451 | // // - RSA_PREMASTER_SIZE is 48 | ||
452 | // // - CURVE25519_KEYSIZE is 32 | ||
453 | // // - master_secret[] is 48 | ||
393 | } | 454 | } |
394 | 455 | ||
395 | for (i = 0; i < key_size; i++) { | 456 | for (i = 0; i < key_size; i++) { |
@@ -407,26 +468,43 @@ static void hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size, | |||
407 | md5sha_hash(&pre->hashed_key_xor_opad, key_xor_opad, SHA_INSIZE); | 468 | md5sha_hash(&pre->hashed_key_xor_opad, key_xor_opad, SHA_INSIZE); |
408 | } | 469 | } |
409 | 470 | ||
410 | static unsigned hmac(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_size, ...) | 471 | static unsigned hmac_sha_precomputed_v( |
472 | hmac_precomputed_t *pre, | ||
473 | uint8_t *out, | ||
474 | va_list va) | ||
475 | { | ||
476 | uint8_t *text; | ||
477 | unsigned len; | ||
478 | |||
479 | /* pre->hashed_key_xor_ipad contains unclosed "H((key XOR ipad) +" state */ | ||
480 | /* pre->hashed_key_xor_opad contains unclosed "H((key XOR opad) +" state */ | ||
481 | |||
482 | /* calculate out = H((key XOR ipad) + text) */ | ||
483 | while ((text = va_arg(va, uint8_t*)) != NULL) { | ||
484 | unsigned text_size = va_arg(va, unsigned); | ||
485 | md5sha_hash(&pre->hashed_key_xor_ipad, text, text_size); | ||
486 | } | ||
487 | len = sha_end(&pre->hashed_key_xor_ipad, out); | ||
488 | |||
489 | /* out = H((key XOR opad) + out) */ | ||
490 | md5sha_hash(&pre->hashed_key_xor_opad, out, len); | ||
491 | return sha_end(&pre->hashed_key_xor_opad, out); | ||
492 | } | ||
493 | |||
494 | static unsigned hmac_sha_precomputed(hmac_precomputed_t *pre_init, uint8_t *out, ...) | ||
411 | { | 495 | { |
412 | hmac_precomputed_t pre; | 496 | hmac_precomputed_t pre; |
413 | va_list va; | 497 | va_list va; |
414 | unsigned len; | 498 | unsigned len; |
415 | 499 | ||
416 | va_start(va, key_size); | 500 | va_start(va, out); |
417 | 501 | pre = *pre_init; /* struct copy */ | |
418 | hmac_begin(&pre, key, key_size, | ||
419 | (tls->MAC_size == SHA256_OUTSIZE) | ||
420 | ? sha256_begin | ||
421 | : sha1_begin | ||
422 | ); | ||
423 | len = hmac_sha_precomputed_v(&pre, out, va); | 502 | len = hmac_sha_precomputed_v(&pre, out, va); |
424 | |||
425 | va_end(va); | 503 | va_end(va); |
426 | return len; | 504 | return len; |
427 | } | 505 | } |
428 | 506 | ||
429 | static unsigned hmac_sha256(/*tls_state_t *tls,*/ uint8_t *out, uint8_t *key, unsigned key_size, ...) | 507 | static unsigned hmac(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_size, ...) |
430 | { | 508 | { |
431 | hmac_precomputed_t pre; | 509 | hmac_precomputed_t pre; |
432 | va_list va; | 510 | va_list va; |
@@ -434,7 +512,11 @@ static unsigned hmac_sha256(/*tls_state_t *tls,*/ uint8_t *out, uint8_t *key, un | |||
434 | 512 | ||
435 | va_start(va, key_size); | 513 | va_start(va, key_size); |
436 | 514 | ||
437 | hmac_begin(&pre, key, key_size, sha256_begin); | 515 | hmac_begin(&pre, key, key_size, |
516 | (tls->MAC_size == SHA256_OUTSIZE) | ||
517 | ? sha256_begin | ||
518 | : sha1_begin | ||
519 | ); | ||
438 | len = hmac_sha_precomputed_v(&pre, out, va); | 520 | len = hmac_sha_precomputed_v(&pre, out, va); |
439 | 521 | ||
440 | va_end(va); | 522 | va_end(va); |
@@ -449,8 +531,9 @@ static unsigned hmac_sha256(/*tls_state_t *tls,*/ uint8_t *out, uint8_t *key, un | |||
449 | // document and in TLS documents published prior to this document when | 531 | // document and in TLS documents published prior to this document when |
450 | // TLS 1.2 is negotiated. | 532 | // TLS 1.2 is negotiated. |
451 | // ^^^^^^^^^^^^^ IMPORTANT! | 533 | // ^^^^^^^^^^^^^ IMPORTANT! |
452 | // PRF uses sha256 regardless of cipher (at least for all ciphers | 534 | // PRF uses sha256 regardless of cipher for all ciphers |
453 | // defined by RFC5246). It's not sha1 for AES_128_CBC_SHA! | 535 | // defined by RFC 5246. It's not sha1 for AES_128_CBC_SHA! |
536 | // However, for _SHA384 ciphers, it's sha384. See RFC 5288,5289. | ||
454 | //... | 537 | //... |
455 | // P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) + | 538 | // P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) + |
456 | // HMAC_hash(secret, A(2) + seed) + | 539 | // HMAC_hash(secret, A(2) + seed) + |
@@ -472,12 +555,19 @@ static unsigned hmac_sha256(/*tls_state_t *tls,*/ uint8_t *out, uint8_t *key, un | |||
472 | // PRF(secret, label, seed) = P_<hash>(secret, label + seed) | 555 | // PRF(secret, label, seed) = P_<hash>(secret, label + seed) |
473 | // | 556 | // |
474 | // The label is an ASCII string. | 557 | // The label is an ASCII string. |
558 | // | ||
559 | // RFC 5288: | ||
560 | // For cipher suites ending with _SHA256, the PRF is the TLS PRF | ||
561 | // with SHA-256 as the hash function. | ||
562 | // For cipher suites ending with _SHA384, the PRF is the TLS PRF | ||
563 | // with SHA-384 as the hash function. | ||
475 | static void prf_hmac_sha256(/*tls_state_t *tls,*/ | 564 | static void prf_hmac_sha256(/*tls_state_t *tls,*/ |
476 | uint8_t *outbuf, unsigned outbuf_size, | 565 | uint8_t *outbuf, unsigned outbuf_size, |
477 | uint8_t *secret, unsigned secret_size, | 566 | uint8_t *secret, unsigned secret_size, |
478 | const char *label, | 567 | const char *label, |
479 | uint8_t *seed, unsigned seed_size) | 568 | uint8_t *seed, unsigned seed_size) |
480 | { | 569 | { |
570 | hmac_precomputed_t pre; | ||
481 | uint8_t a[TLS_MAX_MAC_SIZE]; | 571 | uint8_t a[TLS_MAX_MAC_SIZE]; |
482 | uint8_t *out_p = outbuf; | 572 | uint8_t *out_p = outbuf; |
483 | unsigned label_size = strlen(label); | 573 | unsigned label_size = strlen(label); |
@@ -485,28 +575,28 @@ static void prf_hmac_sha256(/*tls_state_t *tls,*/ | |||
485 | 575 | ||
486 | /* In P_hash() calculation, "seed" is "label + seed": */ | 576 | /* In P_hash() calculation, "seed" is "label + seed": */ |
487 | #define SEED label, label_size, seed, seed_size | 577 | #define SEED label, label_size, seed, seed_size |
488 | #define SECRET secret, secret_size | ||
489 | #define A a, MAC_size | 578 | #define A a, MAC_size |
490 | 579 | ||
580 | hmac_begin(&pre, secret, secret_size, sha256_begin); | ||
581 | |||
491 | /* A(1) = HMAC_hash(secret, seed) */ | 582 | /* A(1) = HMAC_hash(secret, seed) */ |
492 | hmac_sha256(/*tls,*/ a, SECRET, SEED, NULL); | 583 | hmac_sha_precomputed(&pre, a, SEED, NULL); |
493 | //TODO: convert hmac to precomputed | ||
494 | 584 | ||
495 | for (;;) { | 585 | for (;;) { |
496 | /* HMAC_hash(secret, A(1) + seed) */ | 586 | /* HMAC_hash(secret, A(1) + seed) */ |
497 | if (outbuf_size <= MAC_size) { | 587 | if (outbuf_size <= MAC_size) { |
498 | /* Last, possibly incomplete, block */ | 588 | /* Last, possibly incomplete, block */ |
499 | /* (use a[] as temp buffer) */ | 589 | /* (use a[] as temp buffer) */ |
500 | hmac_sha256(/*tls,*/ a, SECRET, A, SEED, NULL); | 590 | hmac_sha_precomputed(&pre, a, A, SEED, NULL); |
501 | memcpy(out_p, a, outbuf_size); | 591 | memcpy(out_p, a, outbuf_size); |
502 | return; | 592 | return; |
503 | } | 593 | } |
504 | /* Not last block. Store directly to result buffer */ | 594 | /* Not last block. Store directly to result buffer */ |
505 | hmac_sha256(/*tls,*/ out_p, SECRET, A, SEED, NULL); | 595 | hmac_sha_precomputed(&pre, out_p, A, SEED, NULL); |
506 | out_p += MAC_size; | 596 | out_p += MAC_size; |
507 | outbuf_size -= MAC_size; | 597 | outbuf_size -= MAC_size; |
508 | /* A(2) = HMAC_hash(secret, A(1)) */ | 598 | /* A(2) = HMAC_hash(secret, A(1)) */ |
509 | hmac_sha256(/*tls,*/ a, SECRET, A, NULL); | 599 | hmac_sha_precomputed(&pre, a, A, NULL); |
510 | } | 600 | } |
511 | #undef A | 601 | #undef A |
512 | #undef SECRET | 602 | #undef SECRET |
@@ -566,17 +656,24 @@ static void *tls_get_outbuf(tls_state_t *tls, int len) | |||
566 | return tls->outbuf + OUTBUF_PFX; | 656 | return tls->outbuf + OUTBUF_PFX; |
567 | } | 657 | } |
568 | 658 | ||
569 | static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | 659 | static void *tls_get_zeroed_outbuf(tls_state_t *tls, int len) |
660 | { | ||
661 | void *record = tls_get_outbuf(tls, len); | ||
662 | memset(record, 0, len); | ||
663 | return record; | ||
664 | } | ||
665 | |||
666 | static void xwrite_encrypted_and_hmac_signed(tls_state_t *tls, unsigned size, unsigned type) | ||
570 | { | 667 | { |
571 | uint8_t *buf = tls->outbuf + OUTBUF_PFX; | 668 | uint8_t *buf = tls->outbuf + OUTBUF_PFX; |
572 | struct record_hdr *xhdr; | 669 | struct record_hdr *xhdr; |
573 | uint8_t padding_length; | 670 | uint8_t padding_length; |
574 | 671 | ||
575 | xhdr = (void*)(buf - RECHDR_LEN); | 672 | xhdr = (void*)(buf - RECHDR_LEN); |
576 | if (CIPHER_ID1 != TLS_RSA_WITH_NULL_SHA256 /* if "no encryption" can't be selected */ | 673 | if (!ALLOW_RSA_NULL_SHA256 /* if "no encryption" can't be selected */ |
577 | || tls->cipher_id != TLS_RSA_WITH_NULL_SHA256 /* or if it wasn't selected */ | 674 | || tls->cipher_id != TLS_RSA_WITH_NULL_SHA256 /* or if it wasn't selected */ |
578 | ) { | 675 | ) { |
579 | xhdr = (void*)(buf - RECHDR_LEN - AES_BLOCKSIZE); /* place for IV */ | 676 | xhdr = (void*)(buf - RECHDR_LEN - AES_BLOCK_SIZE); /* place for IV */ |
580 | } | 677 | } |
581 | 678 | ||
582 | xhdr->type = type; | 679 | xhdr->type = type; |
@@ -598,7 +695,7 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | |||
598 | 695 | ||
599 | size += tls->MAC_size; | 696 | size += tls->MAC_size; |
600 | 697 | ||
601 | // RFC 5246 | 698 | // RFC 5246: |
602 | // 6.2.3.1. Null or Standard Stream Cipher | 699 | // 6.2.3.1. Null or Standard Stream Cipher |
603 | // | 700 | // |
604 | // Stream ciphers (including BulkCipherAlgorithm.null; see Appendix A.6) | 701 | // Stream ciphers (including BulkCipherAlgorithm.null; see Appendix A.6) |
@@ -631,7 +728,7 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | |||
631 | // -------- ----------- ---------- -------------- | 728 | // -------- ----------- ---------- -------------- |
632 | // SHA HMAC-SHA1 20 20 | 729 | // SHA HMAC-SHA1 20 20 |
633 | // SHA256 HMAC-SHA256 32 32 | 730 | // SHA256 HMAC-SHA256 32 32 |
634 | if (CIPHER_ID1 == TLS_RSA_WITH_NULL_SHA256 | 731 | if (ALLOW_RSA_NULL_SHA256 |
635 | && tls->cipher_id == TLS_RSA_WITH_NULL_SHA256 | 732 | && tls->cipher_id == TLS_RSA_WITH_NULL_SHA256 |
636 | ) { | 733 | ) { |
637 | /* No encryption, only signing */ | 734 | /* No encryption, only signing */ |
@@ -679,7 +776,7 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | |||
679 | // AES_128_CBC Block 16 16 16 | 776 | // AES_128_CBC Block 16 16 16 |
680 | // AES_256_CBC Block 32 16 16 | 777 | // AES_256_CBC Block 32 16 16 |
681 | 778 | ||
682 | tls_get_random(buf - AES_BLOCKSIZE, AES_BLOCKSIZE); /* IV */ | 779 | tls_get_random(buf - AES_BLOCK_SIZE, AES_BLOCK_SIZE); /* IV */ |
683 | dbg("before crypt: 5 hdr + %u data + %u hash bytes\n", | 780 | dbg("before crypt: 5 hdr + %u data + %u hash bytes\n", |
684 | size - tls->MAC_size, tls->MAC_size); | 781 | size - tls->MAC_size, tls->MAC_size); |
685 | 782 | ||
@@ -699,23 +796,23 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | |||
699 | // If you need no bytes to reach BLOCKSIZE, you have to pad a full | 796 | // If you need no bytes to reach BLOCKSIZE, you have to pad a full |
700 | // BLOCKSIZE with bytes of value (BLOCKSIZE-1). | 797 | // BLOCKSIZE with bytes of value (BLOCKSIZE-1). |
701 | // It's ok to have more than minimum padding, but we do minimum. | 798 | // It's ok to have more than minimum padding, but we do minimum. |
702 | padding_length = (~size) & (AES_BLOCKSIZE - 1); | 799 | padding_length = (~size) & (AES_BLOCK_SIZE - 1); |
703 | do { | 800 | do { |
704 | buf[size++] = padding_length; /* padding */ | 801 | buf[size++] = padding_length; /* padding */ |
705 | } while ((size & (AES_BLOCKSIZE - 1)) != 0); | 802 | } while ((size & (AES_BLOCK_SIZE - 1)) != 0); |
706 | 803 | ||
707 | /* Encrypt content+MAC+padding in place */ | 804 | /* Encrypt content+MAC+padding in place */ |
708 | aes_cbc_encrypt( | 805 | aes_cbc_encrypt( |
709 | tls->client_write_key, tls->key_size, /* selects 128/256 */ | 806 | &tls->aes_encrypt, /* selects 128/256 */ |
710 | buf - AES_BLOCKSIZE, /* IV */ | 807 | buf - AES_BLOCK_SIZE, /* IV */ |
711 | buf, size, /* plaintext */ | 808 | buf, size, /* plaintext */ |
712 | buf /* ciphertext */ | 809 | buf /* ciphertext */ |
713 | ); | 810 | ); |
714 | 811 | ||
715 | /* Write out */ | 812 | /* Write out */ |
716 | dbg("writing 5 + %u IV + %u encrypted bytes, padding_length:0x%02x\n", | 813 | dbg("writing 5 + %u IV + %u encrypted bytes, padding_length:0x%02x\n", |
717 | AES_BLOCKSIZE, size, padding_length); | 814 | AES_BLOCK_SIZE, size, padding_length); |
718 | size += AES_BLOCKSIZE; /* + IV */ | 815 | size += AES_BLOCK_SIZE; /* + IV */ |
719 | xhdr->len16_hi = size >> 8; | 816 | xhdr->len16_hi = size >> 8; |
720 | xhdr->len16_lo = size & 0xff; | 817 | xhdr->len16_lo = size & 0xff; |
721 | dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size); | 818 | dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size); |
@@ -723,28 +820,114 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | |||
723 | dbg("wrote %u bytes\n", (int)RECHDR_LEN + size); | 820 | dbg("wrote %u bytes\n", (int)RECHDR_LEN + size); |
724 | } | 821 | } |
725 | 822 | ||
823 | /* Example how GCM encryption combines nonce, aad, input and generates | ||
824 | * "header | exp_nonce | encrypted output | tag": | ||
825 | * nonce:0d 6a 26 31 00 00 00 00 00 00 00 01 (implicit 4 bytes (derived from master secret), then explicit 8 bytes) | ||
826 | * aad: 00 00 00 00 00 00 00 01 17 03 03 00 1c | ||
827 | * in: 47 45 54 20 2f 69 6e 64 65 78 2e 68 74 6d 6c 20 48 54 54 50 2f 31 2e 30 0d 0a 0d 0a "GET /index.html HTTP/1.0\r\n\r\n" (0x1c bytes) | ||
828 | * out: f7 8a b2 8f 78 0e f6 d5 76 17 2e b5 6d 46 59 56 8b 46 9f 0b d9 2c 35 28 13 66 19 be | ||
829 | * tag: c2 86 ce 4a 50 4a d0 aa 50 b3 76 5c 49 2a 3f 33 | ||
830 | * sent: 17 03 03 00 34|00 00 00 00 00 00 00 01|f7 8a b2 8f 78 0e f6 d5 76 17 2e b5 6d 46 59 56 8b 46 9f 0b d9 2c 35 28 13 66 19 be|c2 86 ce 4a 50 4a d0 aa 50 b3 76 5c 49 2a 3f 33 | ||
831 | * .............................................^^ buf points here | ||
832 | */ | ||
833 | static void xwrite_encrypted_aesgcm(tls_state_t *tls, unsigned size, unsigned type) | ||
834 | { | ||
835 | #define COUNTER(v) (*(uint32_t*)(v + 12)) | ||
836 | |||
837 | uint8_t aad[13 + 3] ALIGNED_long; /* +3 creates [16] buffer, simplifying GHASH() */ | ||
838 | uint8_t nonce[12 + 4] ALIGNED_long; /* +4 creates space for AES block counter */ | ||
839 | uint8_t scratch[AES_BLOCK_SIZE] ALIGNED_long; //[16] | ||
840 | uint8_t authtag[AES_BLOCK_SIZE] ALIGNED_long; //[16] | ||
841 | uint8_t *buf; | ||
842 | struct record_hdr *xhdr; | ||
843 | unsigned remaining; | ||
844 | unsigned cnt; | ||
845 | uint64_t t64; | ||
846 | |||
847 | buf = tls->outbuf + OUTBUF_PFX; /* see above for the byte it points to */ | ||
848 | dump_hex("xwrite_encrypted_aesgcm plaintext:%s\n", buf, size); | ||
849 | |||
850 | xhdr = (void*)(buf - 8 - RECHDR_LEN); | ||
851 | xhdr->type = type; /* do it here so that "type" param no longer used */ | ||
852 | |||
853 | aad[8] = type; | ||
854 | aad[9] = TLS_MAJ; | ||
855 | aad[10] = TLS_MIN; | ||
856 | aad[11] = size >> 8; | ||
857 | /* set aad[12], and clear aad[13..15] */ | ||
858 | COUNTER(aad) = SWAP_LE32(size & 0xff); | ||
859 | |||
860 | memcpy(nonce, tls->client_write_IV, 4); | ||
861 | t64 = tls->write_seq64_be; | ||
862 | move_to_unaligned64(nonce + 4, t64); | ||
863 | move_to_unaligned64(aad, t64); | ||
864 | move_to_unaligned64(buf - 8, t64); | ||
865 | /* seq64 is not used later in this func, can increment here */ | ||
866 | tls->write_seq64_be = SWAP_BE64(1 + SWAP_BE64(t64)); | ||
867 | |||
868 | cnt = 1; | ||
869 | remaining = size; | ||
870 | while (remaining != 0) { | ||
871 | unsigned n; | ||
872 | |||
873 | cnt++; | ||
874 | COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */ | ||
875 | aes_encrypt_one_block(&tls->aes_encrypt, nonce, scratch); | ||
876 | n = remaining > AES_BLOCK_SIZE ? AES_BLOCK_SIZE : remaining; | ||
877 | xorbuf(buf, scratch, n); | ||
878 | buf += n; | ||
879 | remaining -= n; | ||
880 | } | ||
881 | |||
882 | aesgcm_GHASH(tls->H, aad, /*sizeof(aad),*/ tls->outbuf + OUTBUF_PFX, size, authtag /*, sizeof(authtag)*/); | ||
883 | COUNTER(nonce) = htonl(1); | ||
884 | aes_encrypt_one_block(&tls->aes_encrypt, nonce, scratch); | ||
885 | xorbuf_aligned_AES_BLOCK_SIZE(authtag, scratch); | ||
886 | |||
887 | memcpy(buf, authtag, sizeof(authtag)); | ||
888 | |||
889 | /* Write out */ | ||
890 | xhdr = (void*)(tls->outbuf + OUTBUF_PFX - 8 - RECHDR_LEN); | ||
891 | size += 8 + sizeof(authtag); | ||
892 | /*xhdr->type = type; - already is */ | ||
893 | xhdr->proto_maj = TLS_MAJ; | ||
894 | xhdr->proto_min = TLS_MIN; | ||
895 | xhdr->len16_hi = size >> 8; | ||
896 | xhdr->len16_lo = size & 0xff; | ||
897 | size += RECHDR_LEN; | ||
898 | dump_raw_out(">> %s\n", xhdr, size); | ||
899 | xwrite(tls->ofd, xhdr, size); | ||
900 | dbg("wrote %u bytes\n", size); | ||
901 | #undef COUNTER | ||
902 | } | ||
903 | |||
904 | static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | ||
905 | { | ||
906 | if (!(tls->flags & ENCRYPTION_AESGCM)) { | ||
907 | xwrite_encrypted_and_hmac_signed(tls, size, type); | ||
908 | return; | ||
909 | } | ||
910 | xwrite_encrypted_aesgcm(tls, size, type); | ||
911 | } | ||
912 | |||
726 | static void xwrite_handshake_record(tls_state_t *tls, unsigned size) | 913 | static void xwrite_handshake_record(tls_state_t *tls, unsigned size) |
727 | { | 914 | { |
728 | //if (!tls->encrypt_on_write) { | 915 | uint8_t *buf = tls->outbuf + OUTBUF_PFX; |
729 | uint8_t *buf = tls->outbuf + OUTBUF_PFX; | 916 | struct record_hdr *xhdr = (void*)(buf - RECHDR_LEN); |
730 | struct record_hdr *xhdr = (void*)(buf - RECHDR_LEN); | ||
731 | 917 | ||
732 | xhdr->type = RECORD_TYPE_HANDSHAKE; | 918 | xhdr->type = RECORD_TYPE_HANDSHAKE; |
733 | xhdr->proto_maj = TLS_MAJ; | 919 | xhdr->proto_maj = TLS_MAJ; |
734 | xhdr->proto_min = TLS_MIN; | 920 | xhdr->proto_min = TLS_MIN; |
735 | xhdr->len16_hi = size >> 8; | 921 | xhdr->len16_hi = size >> 8; |
736 | xhdr->len16_lo = size & 0xff; | 922 | xhdr->len16_lo = size & 0xff; |
737 | dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size); | 923 | dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size); |
738 | xwrite(tls->ofd, xhdr, RECHDR_LEN + size); | 924 | xwrite(tls->ofd, xhdr, RECHDR_LEN + size); |
739 | dbg("wrote %u bytes\n", (int)RECHDR_LEN + size); | 925 | dbg("wrote %u bytes\n", (int)RECHDR_LEN + size); |
740 | // return; | ||
741 | //} | ||
742 | //xwrite_encrypted(tls, size, RECORD_TYPE_HANDSHAKE); | ||
743 | } | 926 | } |
744 | 927 | ||
745 | static void xwrite_and_update_handshake_hash(tls_state_t *tls, unsigned size) | 928 | static void xwrite_and_update_handshake_hash(tls_state_t *tls, unsigned size) |
746 | { | 929 | { |
747 | if (!tls->encrypt_on_write) { | 930 | if (!(tls->flags & ENCRYPT_ON_WRITE)) { |
748 | uint8_t *buf; | 931 | uint8_t *buf; |
749 | 932 | ||
750 | xwrite_handshake_record(tls, size); | 933 | xwrite_handshake_record(tls, size); |
@@ -783,6 +966,51 @@ static const char *alert_text(int code) | |||
783 | return itoa(code); | 966 | return itoa(code); |
784 | } | 967 | } |
785 | 968 | ||
969 | static void tls_aesgcm_decrypt(tls_state_t *tls, uint8_t *buf, int size) | ||
970 | { | ||
971 | #define COUNTER(v) (*(uint32_t*)(v + 12)) | ||
972 | |||
973 | //uint8_t aad[13 + 3] ALIGNED_long; /* +3 creates [16] buffer, simplifying GHASH() */ | ||
974 | uint8_t nonce[12 + 4] ALIGNED_long; /* +4 creates space for AES block counter */ | ||
975 | uint8_t scratch[AES_BLOCK_SIZE] ALIGNED_long; //[16] | ||
976 | //uint8_t authtag[AES_BLOCK_SIZE] ALIGNED_long; //[16] | ||
977 | unsigned remaining; | ||
978 | unsigned cnt; | ||
979 | |||
980 | //memcpy(aad, buf, 8); | ||
981 | //aad[8] = type; | ||
982 | //aad[9] = TLS_MAJ; | ||
983 | //aad[10] = TLS_MIN; | ||
984 | //aad[11] = size >> 8; | ||
985 | ///* set aad[12], and clear aad[13..15] */ | ||
986 | //COUNTER(aad) = SWAP_LE32(size & 0xff); | ||
987 | |||
988 | memcpy(nonce, tls->server_write_IV, 4); | ||
989 | memcpy(nonce + 4, buf, 8); | ||
990 | |||
991 | cnt = 1; | ||
992 | remaining = size; | ||
993 | while (remaining != 0) { | ||
994 | unsigned n; | ||
995 | |||
996 | cnt++; | ||
997 | COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */ | ||
998 | aes_encrypt_one_block(&tls->aes_decrypt, nonce, scratch); | ||
999 | n = remaining > AES_BLOCK_SIZE ? AES_BLOCK_SIZE : remaining; | ||
1000 | xorbuf3(buf, scratch, buf + 8, n); | ||
1001 | buf += n; | ||
1002 | remaining -= n; | ||
1003 | } | ||
1004 | |||
1005 | //aesgcm_GHASH(tls->H, aad, tls->inbuf + RECHDR_LEN, size, authtag); | ||
1006 | //COUNTER(nonce) = htonl(1); | ||
1007 | //aes_encrypt_one_block(&tls->aes_encrypt, nonce, scratch); | ||
1008 | //xorbuf_aligned_AES_BLOCK_SIZE(authtag, scratch); | ||
1009 | |||
1010 | //memcmp(buf, authtag, sizeof(authtag)) || DIE("HASH DOES NOT MATCH!"); | ||
1011 | #undef COUNTER | ||
1012 | } | ||
1013 | |||
786 | static int tls_xread_record(tls_state_t *tls, const char *expected) | 1014 | static int tls_xread_record(tls_state_t *tls, const char *expected) |
787 | { | 1015 | { |
788 | struct record_hdr *xhdr; | 1016 | struct record_hdr *xhdr; |
@@ -853,34 +1081,43 @@ static int tls_xread_record(tls_state_t *tls, const char *expected) | |||
853 | sz = target - RECHDR_LEN; | 1081 | sz = target - RECHDR_LEN; |
854 | 1082 | ||
855 | /* Needs to be decrypted? */ | 1083 | /* Needs to be decrypted? */ |
856 | if (tls->min_encrypted_len_on_read > tls->MAC_size) { | 1084 | if (tls->min_encrypted_len_on_read != 0) { |
857 | uint8_t *p = tls->inbuf + RECHDR_LEN; | 1085 | if (sz < (int)tls->min_encrypted_len_on_read) |
858 | int padding_len; | 1086 | bb_error_msg_and_die("bad encrypted len:%u", sz); |
859 | 1087 | ||
860 | if (sz & (AES_BLOCKSIZE-1) | 1088 | if (tls->flags & ENCRYPTION_AESGCM) { |
861 | || sz < (int)tls->min_encrypted_len_on_read | 1089 | /* AESGCM */ |
862 | ) { | 1090 | uint8_t *p = tls->inbuf + RECHDR_LEN; |
863 | bb_error_msg_and_die("bad encrypted len:%u < %u", | 1091 | |
864 | sz, tls->min_encrypted_len_on_read); | 1092 | sz -= 8 + AES_BLOCK_SIZE; /* we will overwrite nonce, drop hash */ |
1093 | tls_aesgcm_decrypt(tls, p, sz); | ||
1094 | dbg("encrypted size:%u\n", sz); | ||
1095 | } else | ||
1096 | if (tls->min_encrypted_len_on_read > tls->MAC_size) { | ||
1097 | /* AES+SHA */ | ||
1098 | uint8_t *p = tls->inbuf + RECHDR_LEN; | ||
1099 | int padding_len; | ||
1100 | |||
1101 | if (sz & (AES_BLOCK_SIZE-1)) | ||
1102 | bb_error_msg_and_die("bad encrypted len:%u", sz); | ||
1103 | |||
1104 | /* Decrypt content+MAC+padding, moving it over IV in the process */ | ||
1105 | sz -= AES_BLOCK_SIZE; /* we will overwrite IV now */ | ||
1106 | aes_cbc_decrypt( | ||
1107 | &tls->aes_decrypt, /* selects 128/256 */ | ||
1108 | p, /* IV */ | ||
1109 | p + AES_BLOCK_SIZE, sz, /* ciphertext */ | ||
1110 | p /* plaintext */ | ||
1111 | ); | ||
1112 | padding_len = p[sz - 1]; | ||
1113 | dbg("encrypted size:%u type:0x%02x padding_length:0x%02x\n", sz, p[0], padding_len); | ||
1114 | padding_len++; | ||
1115 | sz -= tls->MAC_size + padding_len; /* drop MAC and padding */ | ||
1116 | } else { | ||
1117 | /* if nonzero, then it's TLS_RSA_WITH_NULL_SHA256: drop MAC */ | ||
1118 | /* else: no encryption yet on input, subtract zero = NOP */ | ||
1119 | sz -= tls->min_encrypted_len_on_read; | ||
865 | } | 1120 | } |
866 | /* Decrypt content+MAC+padding, moving it over IV in the process */ | ||
867 | sz -= AES_BLOCKSIZE; /* we will overwrite IV now */ | ||
868 | aes_cbc_decrypt( | ||
869 | tls->server_write_key, tls->key_size, /* selects 128/256 */ | ||
870 | p, /* IV */ | ||
871 | p + AES_BLOCKSIZE, sz, /* ciphertext */ | ||
872 | p /* plaintext */ | ||
873 | ); | ||
874 | padding_len = p[sz - 1]; | ||
875 | dbg("encrypted size:%u type:0x%02x padding_length:0x%02x\n", sz, p[0], padding_len); | ||
876 | padding_len++; | ||
877 | sz -= tls->MAC_size + padding_len; /* drop MAC and padding */ | ||
878 | //if (sz < 0) | ||
879 | // bb_error_msg_and_die("bad padding size:%u", padding_len); | ||
880 | } else { | ||
881 | /* if nonzero, then it's TLS_RSA_WITH_NULL_SHA256: drop MAC */ | ||
882 | /* else: no encryption yet on input, subtract zero = NOP */ | ||
883 | sz -= tls->min_encrypted_len_on_read; | ||
884 | } | 1121 | } |
885 | if (sz < 0) | 1122 | if (sz < 0) |
886 | bb_error_msg_and_die("encrypted data too short"); | 1123 | bb_error_msg_and_die("encrypted data too short"); |
@@ -921,7 +1158,8 @@ static int tls_xread_record(tls_state_t *tls, const char *expected) | |||
921 | * in our FINISHED record must include data of incoming packets too! | 1158 | * in our FINISHED record must include data of incoming packets too! |
922 | */ | 1159 | */ |
923 | if (tls->inbuf[0] == RECORD_TYPE_HANDSHAKE | 1160 | if (tls->inbuf[0] == RECORD_TYPE_HANDSHAKE |
924 | && tls->MAC_size != 0 /* do we know which hash to use? (server_hello() does not!) */ | 1161 | /* HANDSHAKE HASH: */ |
1162 | // && do_we_know_which_hash_to_use /* server_hello() might not know it in the future! */ | ||
925 | ) { | 1163 | ) { |
926 | hash_handshake(tls, "<< hash:%s", tls->inbuf + RECHDR_LEN, sz); | 1164 | hash_handshake(tls, "<< hash:%s", tls->inbuf + RECHDR_LEN, sz); |
927 | } | 1165 | } |
@@ -930,6 +1168,13 @@ static int tls_xread_record(tls_state_t *tls, const char *expected) | |||
930 | return sz; | 1168 | return sz; |
931 | } | 1169 | } |
932 | 1170 | ||
1171 | static void binary_to_pstm(pstm_int *pstm_n, uint8_t *bin_ptr, unsigned len) | ||
1172 | { | ||
1173 | pstm_init_for_read_unsigned_bin(/*pool:*/ NULL, pstm_n, len); | ||
1174 | pstm_read_unsigned_bin(pstm_n, bin_ptr, len); | ||
1175 | //return bin_ptr + len; | ||
1176 | } | ||
1177 | |||
933 | /* | 1178 | /* |
934 | * DER parsing routines | 1179 | * DER parsing routines |
935 | */ | 1180 | */ |
@@ -1001,9 +1246,7 @@ static void der_binary_to_pstm(pstm_int *pstm_n, uint8_t *der, uint8_t *end) | |||
1001 | unsigned len = get_der_len(&bin_ptr, der, end); | 1246 | unsigned len = get_der_len(&bin_ptr, der, end); |
1002 | 1247 | ||
1003 | dbg_der("binary bytes:%u, first:0x%02x\n", len, bin_ptr[0]); | 1248 | dbg_der("binary bytes:%u, first:0x%02x\n", len, bin_ptr[0]); |
1004 | pstm_init_for_read_unsigned_bin(/*pool:*/ NULL, pstm_n, len); | 1249 | binary_to_pstm(pstm_n, bin_ptr, len); |
1005 | pstm_read_unsigned_bin(pstm_n, bin_ptr, len); | ||
1006 | //return bin + len; | ||
1007 | } | 1250 | } |
1008 | 1251 | ||
1009 | static void find_key_in_der_cert(tls_state_t *tls, uint8_t *der, int len) | 1252 | static void find_key_in_der_cert(tls_state_t *tls, uint8_t *der, int len) |
@@ -1086,10 +1329,20 @@ static void find_key_in_der_cert(tls_state_t *tls, uint8_t *der, int len) | |||
1086 | * publicKey (BIT STRING) | 1329 | * publicKey (BIT STRING) |
1087 | * | 1330 | * |
1088 | * We need Certificate.tbsCertificate.subjectPublicKeyInfo.publicKey | 1331 | * We need Certificate.tbsCertificate.subjectPublicKeyInfo.publicKey |
1332 | * | ||
1333 | * Example of an ECDSA key: | ||
1334 | * SEQ 0x59 bytes (subjectPublicKeyInfo): 3059 | ||
1335 | * SEQ 0x13 bytes (algorithm): 3013 | ||
1336 | * OID 7 bytes: 0607 2a8648ce3d0201 (OID_ECDSA_KEY_ALG 42.134.72.206.61.2.1) | ||
1337 | * OID 8 bytes: 0608 2a8648ce3d030107 (OID_EC_prime256v1 42.134.72.206.61.3.1.7) | ||
1338 | * BITSTRING 0x42 bytes (publicKey): 0342 | ||
1339 | * 0004 53af f65e 50cc 7959 7e29 0171 c75c | ||
1340 | * 7335 e07d f45b 9750 b797 3a38 aebb 2ac6 | ||
1341 | * 8329 2748 e77e 41cb d482 2ce6 05ec a058 | ||
1342 | * f3ab d561 2f4c d845 9ad3 7252 e3de bd3b | ||
1343 | * 9012 | ||
1089 | */ | 1344 | */ |
1090 | uint8_t *end = der + len; | 1345 | uint8_t *end = der + len; |
1091 | uint8_t tag_class, pc, tag_number; | ||
1092 | int version_present; | ||
1093 | 1346 | ||
1094 | /* enter "Certificate" item: [der, end) will be only Cert */ | 1347 | /* enter "Certificate" item: [der, end) will be only Cert */ |
1095 | der = enter_der_item(der, &end); | 1348 | der = enter_der_item(der, &end); |
@@ -1106,13 +1359,11 @@ static void find_key_in_der_cert(tls_state_t *tls, uint8_t *der, int len) | |||
1106 | * (constructed), and a tag number of 0 (see ITU-T X.690 sections 8.1.2 | 1359 | * (constructed), and a tag number of 0 (see ITU-T X.690 sections 8.1.2 |
1107 | * and 8.14). | 1360 | * and 8.14). |
1108 | */ | 1361 | */ |
1109 | tag_class = der[0] >> 6; /* bits 8-7 */ | 1362 | /* bits 7-6: 10 */ |
1110 | pc = (der[0] & 32) >> 5; /* bit 6 */ | 1363 | /* bit 5: 1 */ |
1111 | tag_number = der[0] & 31; /* bits 5-1 */ | 1364 | /* bits 4-0: 00000 */ |
1112 | version_present = tag_class == 2 && pc == 1 && tag_number == 0; | 1365 | if (der[0] == 0xa0) |
1113 | if (version_present) { | ||
1114 | der = skip_der_item(der, end); /* version */ | 1366 | der = skip_der_item(der, end); /* version */ |
1115 | } | ||
1116 | 1367 | ||
1117 | /* skip up to subjectPublicKeyInfo */ | 1368 | /* skip up to subjectPublicKeyInfo */ |
1118 | der = skip_der_item(der, end); /* serialNumber */ | 1369 | der = skip_der_item(der, end); /* serialNumber */ |
@@ -1124,40 +1375,67 @@ static void find_key_in_der_cert(tls_state_t *tls, uint8_t *der, int len) | |||
1124 | /* enter subjectPublicKeyInfo */ | 1375 | /* enter subjectPublicKeyInfo */ |
1125 | der = enter_der_item(der, &end); | 1376 | der = enter_der_item(der, &end); |
1126 | { /* check subjectPublicKeyInfo.algorithm */ | 1377 | { /* check subjectPublicKeyInfo.algorithm */ |
1127 | static const uint8_t expected[] = { | 1378 | static const uint8_t OID_RSA_KEY_ALG[] = { |
1128 | 0x30,0x0d, // SEQ 13 bytes | 1379 | 0x30,0x0d, // SEQ 13 bytes |
1129 | 0x06,0x09, 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01, // OID RSA_KEY_ALG 42.134.72.134.247.13.1.1.1 | 1380 | 0x06,0x09, 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01, //OID_RSA_KEY_ALG 42.134.72.134.247.13.1.1.1 |
1130 | //0x05,0x00, // NULL | 1381 | //0x05,0x00, // NULL |
1131 | }; | 1382 | }; |
1132 | if (memcmp(der, expected, sizeof(expected)) != 0) | 1383 | static const uint8_t OID_ECDSA_KEY_ALG[] = { |
1133 | bb_error_msg_and_die("not RSA key"); | 1384 | 0x30,0x13, // SEQ 0x13 bytes |
1385 | 0x06,0x07, 0x2a,0x86,0x48,0xce,0x3d,0x02,0x01, //OID_ECDSA_KEY_ALG 42.134.72.206.61.2.1 | ||
1386 | //allow any curve code for now... | ||
1387 | // 0x06,0x08, 0x2a,0x86,0x48,0xce,0x3d,0x03,0x01,0x07, //OID_EC_prime256v1 42.134.72.206.61.3.1.7 | ||
1388 | //RFC 3279: | ||
1389 | //42.134.72.206.61.3 is ellipticCurve | ||
1390 | //42.134.72.206.61.3.0 is c-TwoCurve | ||
1391 | //42.134.72.206.61.3.1 is primeCurve | ||
1392 | //42.134.72.206.61.3.1.7 is curve_secp256r1 | ||
1393 | }; | ||
1394 | if (memcmp(der, OID_RSA_KEY_ALG, sizeof(OID_RSA_KEY_ALG)) == 0) { | ||
1395 | dbg("RSA key\n"); | ||
1396 | tls->flags |= GOT_CERT_RSA_KEY_ALG; | ||
1397 | } else | ||
1398 | if (memcmp(der, OID_ECDSA_KEY_ALG, sizeof(OID_ECDSA_KEY_ALG)) == 0) { | ||
1399 | dbg("ECDSA key\n"); | ||
1400 | //UNUSED: tls->flags |= GOT_CERT_ECDSA_KEY_ALG; | ||
1401 | } else | ||
1402 | bb_error_msg_and_die("not RSA or ECDSA cert"); | ||
1134 | } | 1403 | } |
1135 | /* skip subjectPublicKeyInfo.algorithm */ | ||
1136 | der = skip_der_item(der, end); | ||
1137 | /* enter subjectPublicKeyInfo.publicKey */ | ||
1138 | // die_if_not_this_der_type(der, end, 0x03); /* must be BITSTRING */ | ||
1139 | der = enter_der_item(der, &end); | ||
1140 | 1404 | ||
1141 | /* parse RSA key: */ | 1405 | if (tls->flags & GOT_CERT_RSA_KEY_ALG) { |
1142 | //based on getAsnRsaPubKey(), pkcs1ParsePrivBin() is also of note | 1406 | /* parse RSA key: */ |
1143 | dbg("key bytes:%u, first:0x%02x\n", (int)(end - der), der[0]); | 1407 | //based on getAsnRsaPubKey(), pkcs1ParsePrivBin() is also of note |
1144 | if (end - der < 14) xfunc_die(); | 1408 | /* skip subjectPublicKeyInfo.algorithm */ |
1145 | /* example format: | 1409 | der = skip_der_item(der, end); |
1146 | * ignore bits: 00 | 1410 | /* enter subjectPublicKeyInfo.publicKey */ |
1147 | * SEQ 0x018a/394 bytes: 3082018a | 1411 | //die_if_not_this_der_type(der, end, 0x03); /* must be BITSTRING */ |
1148 | * INTEGER 0x0181/385 bytes (modulus): 02820181 XX...XXX | 1412 | der = enter_der_item(der, &end); |
1149 | * INTEGER 3 bytes (exponent): 0203 010001 | 1413 | |
1414 | dbg("key bytes:%u, first:0x%02x\n", (int)(end - der), der[0]); | ||
1415 | if (end - der < 14) | ||
1416 | xfunc_die(); | ||
1417 | /* example format: | ||
1418 | * ignore bits: 00 | ||
1419 | * SEQ 0x018a/394 bytes: 3082018a | ||
1420 | * INTEGER 0x0181/385 bytes (modulus): 02820181 XX...XXX | ||
1421 | * INTEGER 3 bytes (exponent): 0203 010001 | ||
1422 | */ | ||
1423 | if (*der != 0) /* "ignore bits", should be 0 */ | ||
1424 | xfunc_die(); | ||
1425 | der++; | ||
1426 | der = enter_der_item(der, &end); /* enter SEQ */ | ||
1427 | /* memset(tls->hsd->server_rsa_pub_key, 0, sizeof(tls->hsd->server_rsa_pub_key)); - already is */ | ||
1428 | der_binary_to_pstm(&tls->hsd->server_rsa_pub_key.N, der, end); /* modulus */ | ||
1429 | der = skip_der_item(der, end); | ||
1430 | der_binary_to_pstm(&tls->hsd->server_rsa_pub_key.e, der, end); /* exponent */ | ||
1431 | tls->hsd->server_rsa_pub_key.size = pstm_unsigned_bin_size(&tls->hsd->server_rsa_pub_key.N); | ||
1432 | dbg("server_rsa_pub_key.size:%d\n", tls->hsd->server_rsa_pub_key.size); | ||
1433 | } | ||
1434 | /* else: ECDSA key. It is not used for generating encryption keys, | ||
1435 | * it is used only to sign the EC public key (which comes in ServerKey message). | ||
1436 | * Since we do not verify cert validity, verifying signature on EC public key | ||
1437 | * wouldn't add any security. Thus, we do nothing here. | ||
1150 | */ | 1438 | */ |
1151 | if (*der != 0) /* "ignore bits", should be 0 */ | ||
1152 | xfunc_die(); | ||
1153 | der++; | ||
1154 | der = enter_der_item(der, &end); /* enter SEQ */ | ||
1155 | /* memset(tls->hsd->server_rsa_pub_key, 0, sizeof(tls->hsd->server_rsa_pub_key)); - already is */ | ||
1156 | der_binary_to_pstm(&tls->hsd->server_rsa_pub_key.N, der, end); /* modulus */ | ||
1157 | der = skip_der_item(der, end); | ||
1158 | der_binary_to_pstm(&tls->hsd->server_rsa_pub_key.e, der, end); /* exponent */ | ||
1159 | tls->hsd->server_rsa_pub_key.size = pstm_unsigned_bin_size(&tls->hsd->server_rsa_pub_key.N); | ||
1160 | dbg("server_rsa_pub_key.size:%d\n", tls->hsd->server_rsa_pub_key.size); | ||
1161 | } | 1439 | } |
1162 | 1440 | ||
1163 | /* | 1441 | /* |
@@ -1194,6 +1472,56 @@ static ALWAYS_INLINE void fill_handshake_record_hdr(void *buf, unsigned type, un | |||
1194 | 1472 | ||
1195 | static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni) | 1473 | static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni) |
1196 | { | 1474 | { |
1475 | #define NUM_CIPHERS (13 + ALLOW_RSA_NULL_SHA256) | ||
1476 | static const uint8_t ciphers[] = { | ||
1477 | 0x00,(1 + NUM_CIPHERS) * 2, //len16_be | ||
1478 | 0x00,0xFF, //not a cipher - TLS_EMPTY_RENEGOTIATION_INFO_SCSV | ||
1479 | /* ^^^^^^ RFC 5746 Renegotiation Indication Extension - some servers will refuse to work with us otherwise */ | ||
1480 | 0xC0,0x09, // 1 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - ok: wget https://is.gd/ | ||
1481 | 0xC0,0x0A, // 2 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - ok: wget https://is.gd/ | ||
1482 | 0xC0,0x13, // 3 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - ok: openssl s_server ... -cipher ECDHE-RSA-AES128-SHA | ||
1483 | 0xC0,0x14, // 4 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - ok: openssl s_server ... -cipher ECDHE-RSA-AES256-SHA (might fail with older openssl) | ||
1484 | 0xC0,0x23, // 5 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - ok: wget https://is.gd/ | ||
1485 | // 0xC0,0x24, // TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - can't do SHA384 yet | ||
1486 | 0xC0,0x27, // 6 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - ok: openssl s_server ... -cipher ECDHE-RSA-AES128-SHA256 | ||
1487 | // 0xC0,0x28, // TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - can't do SHA384 yet | ||
1488 | 0xC0,0x2B, // 7 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - ok: wget https://is.gd/ | ||
1489 | // 0xC0,0x2C, // TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - wget https://is.gd/: "TLS error from peer (alert code 20): bad MAC" | ||
1490 | //TODO: GCM_SHA384 ciphers can be supported, only need sha384-based PRF? | ||
1491 | 0xC0,0x2F, // 8 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - ok: openssl s_server ... -cipher ECDHE-RSA-AES128-GCM-SHA256 | ||
1492 | // 0xC0,0x30, // TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - openssl s_server ... -cipher ECDHE-RSA-AES256-GCM-SHA384: "decryption failed or bad record mac" | ||
1493 | //possibly these too: | ||
1494 | // 0xC0,0x35, // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA | ||
1495 | // 0xC0,0x36, // TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA | ||
1496 | // 0xC0,0x37, // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 | ||
1497 | // 0xC0,0x38, // TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 - can't do SHA384 yet | ||
1498 | 0x00,0x2F, // 9 TLS_RSA_WITH_AES_128_CBC_SHA - ok: openssl s_server ... -cipher AES128-SHA | ||
1499 | 0x00,0x35, //10 TLS_RSA_WITH_AES_256_CBC_SHA - ok: openssl s_server ... -cipher AES256-SHA | ||
1500 | 0x00,0x3C, //11 TLS_RSA_WITH_AES_128_CBC_SHA256 - ok: openssl s_server ... -cipher AES128-SHA256 | ||
1501 | 0x00,0x3D, //12 TLS_RSA_WITH_AES_256_CBC_SHA256 - ok: openssl s_server ... -cipher AES256-SHA256 | ||
1502 | 0x00,0x9C, //13 TLS_RSA_WITH_AES_128_GCM_SHA256 - ok: openssl s_server ... -cipher AES128-GCM-SHA256 | ||
1503 | // 0x00,0x9D, // TLS_RSA_WITH_AES_256_GCM_SHA384 - openssl s_server ... -cipher AES256-GCM-SHA384: "decryption failed or bad record mac" | ||
1504 | #if ALLOW_RSA_NULL_SHA256 | ||
1505 | 0x00,0x3B, // TLS_RSA_WITH_NULL_SHA256 | ||
1506 | #endif | ||
1507 | 0x01,0x00, //not a cipher - comprtypes_len, comprtype | ||
1508 | }; | ||
1509 | static const uint8_t supported_groups[] = { | ||
1510 | 0x00,0x0a, //extension_type: "supported_groups" | ||
1511 | 0x00,0x04, //ext len | ||
1512 | 0x00,0x02, //list len | ||
1513 | 0x00,0x1d, //curve_x25519 (RFC 7748) | ||
1514 | //0x00,0x17, //curve_secp256r1 | ||
1515 | //0x00,0x18, //curve_secp384r1 | ||
1516 | //0x00,0x19, //curve_secp521r1 | ||
1517 | }; | ||
1518 | //static const uint8_t signature_algorithms[] = { | ||
1519 | // 000d | ||
1520 | // 0020 | ||
1521 | // 001e | ||
1522 | // 0601 0602 0603 0501 0502 0503 0401 0402 0403 0301 0302 0303 0201 0202 0203 | ||
1523 | //}; | ||
1524 | |||
1197 | struct client_hello { | 1525 | struct client_hello { |
1198 | uint8_t type; | 1526 | uint8_t type; |
1199 | uint8_t len24_hi, len24_mid, len24_lo; | 1527 | uint8_t len24_hi, len24_mid, len24_lo; |
@@ -1202,7 +1530,7 @@ static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni) | |||
1202 | uint8_t session_id_len; | 1530 | uint8_t session_id_len; |
1203 | /* uint8_t session_id[]; */ | 1531 | /* uint8_t session_id[]; */ |
1204 | uint8_t cipherid_len16_hi, cipherid_len16_lo; | 1532 | uint8_t cipherid_len16_hi, cipherid_len16_lo; |
1205 | uint8_t cipherid[2 * (2 + !!CIPHER_ID2)]; /* actually variable */ | 1533 | uint8_t cipherid[(1 + NUM_CIPHERS) * 2]; /* actually variable */ |
1206 | uint8_t comprtypes_len; | 1534 | uint8_t comprtypes_len; |
1207 | uint8_t comprtypes[1]; /* actually variable */ | 1535 | uint8_t comprtypes[1]; /* actually variable */ |
1208 | /* Extensions (SNI shown): | 1536 | /* Extensions (SNI shown): |
@@ -1227,14 +1555,20 @@ static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni) | |||
1227 | // 0017 0000 - extended master secret | 1555 | // 0017 0000 - extended master secret |
1228 | }; | 1556 | }; |
1229 | struct client_hello *record; | 1557 | struct client_hello *record; |
1558 | uint8_t *ptr; | ||
1230 | int len; | 1559 | int len; |
1231 | int sni_len = sni ? strnlen(sni, 127 - 9) : 0; | 1560 | int ext_len; |
1561 | int sni_len = sni ? strnlen(sni, 127 - 5) : 0; | ||
1232 | 1562 | ||
1233 | len = sizeof(*record); | 1563 | ext_len = 0; |
1564 | /* is.gd responds with "handshake failure" to our hello if there's no supported_groups element */ | ||
1565 | ext_len += sizeof(supported_groups); | ||
1234 | if (sni_len) | 1566 | if (sni_len) |
1235 | len += 11 + sni_len; | 1567 | ext_len += 9 + sni_len; |
1236 | record = tls_get_outbuf(tls, len); | 1568 | |
1237 | memset(record, 0, len); | 1569 | /* +2 is for "len of all extensions" 2-byte field */ |
1570 | len = sizeof(*record) + 2 + ext_len; | ||
1571 | record = tls_get_zeroed_outbuf(tls, len); | ||
1238 | 1572 | ||
1239 | fill_handshake_record_hdr(record, HANDSHAKE_CLIENT_HELLO, len); | 1573 | fill_handshake_record_hdr(record, HANDSHAKE_CLIENT_HELLO, len); |
1240 | record->proto_maj = TLS_MAJ; /* the "requested" version of the protocol, */ | 1574 | record->proto_maj = TLS_MAJ; /* the "requested" version of the protocol, */ |
@@ -1244,46 +1578,43 @@ static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni) | |||
1244 | memset(record->rand32, 0x11, sizeof(record->rand32)); | 1578 | memset(record->rand32, 0x11, sizeof(record->rand32)); |
1245 | /* record->session_id_len = 0; - already is */ | 1579 | /* record->session_id_len = 0; - already is */ |
1246 | 1580 | ||
1247 | /* record->cipherid_len16_hi = 0; */ | 1581 | BUILD_BUG_ON(sizeof(ciphers) != 2 + (1 + NUM_CIPHERS) * 2 + 2); |
1248 | record->cipherid_len16_lo = sizeof(record->cipherid); | 1582 | memcpy(&record->cipherid_len16_hi, ciphers, sizeof(ciphers)); |
1249 | /* RFC 5746 Renegotiation Indication Extension - some servers will refuse to work with us otherwise */ | ||
1250 | /*record->cipherid[0] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV >> 8; - zero */ | ||
1251 | record->cipherid[1] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV & 0xff; | ||
1252 | if ((CIPHER_ID1 >> 8) != 0) record->cipherid[2] = CIPHER_ID1 >> 8; | ||
1253 | /*************************/ record->cipherid[3] = CIPHER_ID1 & 0xff; | ||
1254 | #if CIPHER_ID2 | ||
1255 | if ((CIPHER_ID2 >> 8) != 0) record->cipherid[4] = CIPHER_ID2 >> 8; | ||
1256 | /*************************/ record->cipherid[5] = CIPHER_ID2 & 0xff; | ||
1257 | #endif | ||
1258 | |||
1259 | record->comprtypes_len = 1; | ||
1260 | /* record->comprtypes[0] = 0; */ | ||
1261 | 1583 | ||
1584 | ptr = (void*)(record + 1); | ||
1585 | *ptr++ = ext_len >> 8; | ||
1586 | *ptr++ = ext_len; | ||
1262 | if (sni_len) { | 1587 | if (sni_len) { |
1263 | uint8_t *p = (void*)(record + 1); | 1588 | //ptr[0] = 0; // |
1264 | //p[0] = 0; // | 1589 | //ptr[1] = 0; //extension_type |
1265 | p[1] = sni_len + 9; //ext_len | 1590 | //ptr[2] = 0; // |
1266 | //p[2] = 0; // | 1591 | ptr[3] = sni_len + 5; //list len |
1267 | //p[3] = 0; //extension_type | 1592 | //ptr[4] = 0; // |
1268 | //p[4] = 0; // | 1593 | ptr[5] = sni_len + 3; //len of 1st SNI |
1269 | p[5] = sni_len + 5; //list len | 1594 | //ptr[6] = 0; //name type |
1270 | //p[6] = 0; // | 1595 | //ptr[7] = 0; // |
1271 | p[7] = sni_len + 3; //len of 1st SNI | 1596 | ptr[8] = sni_len; //name len |
1272 | //p[8] = 0; //name type | 1597 | ptr = mempcpy(&ptr[9], sni, sni_len); |
1273 | //p[9] = 0; // | ||
1274 | p[10] = sni_len; //name len | ||
1275 | memcpy(&p[11], sni, sni_len); | ||
1276 | } | 1598 | } |
1599 | memcpy(ptr, supported_groups, sizeof(supported_groups)); | ||
1277 | 1600 | ||
1278 | dbg(">> CLIENT_HELLO\n"); | 1601 | tls->hsd = xzalloc(sizeof(*tls->hsd)); |
1279 | /* Can hash it only when we know which MAC hash to use */ | 1602 | /* HANDSHAKE HASH: ^^^ + len if need to save saved_client_hello */ |
1280 | /*xwrite_and_update_handshake_hash(tls, len); - WRONG! */ | 1603 | memcpy(tls->hsd->client_and_server_rand32, record->rand32, sizeof(record->rand32)); |
1281 | xwrite_handshake_record(tls, len); | 1604 | /* HANDSHAKE HASH: |
1282 | |||
1283 | tls->hsd = xzalloc(sizeof(*tls->hsd) + len); | ||
1284 | tls->hsd->saved_client_hello_size = len; | 1605 | tls->hsd->saved_client_hello_size = len; |
1285 | memcpy(tls->hsd->saved_client_hello, record, len); | 1606 | memcpy(tls->hsd->saved_client_hello, record, len); |
1286 | memcpy(tls->hsd->client_and_server_rand32, record->rand32, sizeof(record->rand32)); | 1607 | */ |
1608 | dbg(">> CLIENT_HELLO\n"); | ||
1609 | /* Can hash immediately only if we know which MAC hash to use. | ||
1610 | * So far we do know: it's sha256: | ||
1611 | */ | ||
1612 | sha256_begin(&tls->hsd->handshake_hash_ctx); | ||
1613 | xwrite_and_update_handshake_hash(tls, len); | ||
1614 | /* if this would become infeasible: save tls->hsd->saved_client_hello, | ||
1615 | * use "xwrite_handshake_record(tls, len)" here, | ||
1616 | * and hash saved_client_hello later. | ||
1617 | */ | ||
1287 | } | 1618 | } |
1288 | 1619 | ||
1289 | static void get_server_hello(tls_state_t *tls) | 1620 | static void get_server_hello(tls_state_t *tls) |
@@ -1303,7 +1634,7 @@ static void get_server_hello(tls_state_t *tls) | |||
1303 | 1634 | ||
1304 | struct server_hello *hp; | 1635 | struct server_hello *hp; |
1305 | uint8_t *cipherid; | 1636 | uint8_t *cipherid; |
1306 | unsigned cipher; | 1637 | uint8_t cipherid1; |
1307 | int len, len24; | 1638 | int len, len24; |
1308 | 1639 | ||
1309 | len = tls_xread_handshake_block(tls, 74 - 32); | 1640 | len = tls_xread_handshake_block(tls, 74 - 32); |
@@ -1336,33 +1667,87 @@ static void get_server_hello(tls_state_t *tls) | |||
1336 | len24 += 32; /* what len would be if session id would be present */ | 1667 | len24 += 32; /* what len would be if session id would be present */ |
1337 | } | 1668 | } |
1338 | 1669 | ||
1339 | if (len24 < 70 | 1670 | if (len24 < 70) |
1340 | // || cipherid[0] != (CIPHER_ID >> 8) | ||
1341 | // || cipherid[1] != (CIPHER_ID & 0xff) | ||
1342 | // || cipherid[2] != 0 /* comprtype */ | ||
1343 | ) { | ||
1344 | bad_record_die(tls, "'server hello'", len); | 1671 | bad_record_die(tls, "'server hello'", len); |
1345 | } | ||
1346 | dbg("<< SERVER_HELLO\n"); | 1672 | dbg("<< SERVER_HELLO\n"); |
1347 | 1673 | ||
1348 | memcpy(tls->hsd->client_and_server_rand32 + 32, hp->rand32, sizeof(hp->rand32)); | 1674 | memcpy(tls->hsd->client_and_server_rand32 + 32, hp->rand32, sizeof(hp->rand32)); |
1349 | 1675 | ||
1350 | tls->cipher_id = cipher = 0x100 * cipherid[0] + cipherid[1]; | 1676 | /* Set up encryption params based on selected cipher */ |
1351 | dbg("server chose cipher %04x\n", cipher); | 1677 | #if 0 |
1352 | 1678 | 0xC0,0x09, // 1 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - ok: wget https://is.gd/ | |
1353 | if (cipher == TLS_RSA_WITH_AES_128_CBC_SHA) { | 1679 | 0xC0,0x0A, // 2 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - ok: wget https://is.gd/ |
1354 | tls->key_size = AES128_KEYSIZE; | 1680 | 0xC0,0x13, // 3 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - ok: openssl s_server ... -cipher ECDHE-RSA-AES128-SHA |
1355 | tls->MAC_size = SHA1_OUTSIZE; | 1681 | 0xC0,0x14, // 4 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - ok: openssl s_server ... -cipher ECDHE-RSA-AES256-SHA (might fail with older openssl) |
1356 | } | 1682 | 0xC0,0x23, // 5 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - ok: wget https://is.gd/ |
1357 | else { /* TLS_RSA_WITH_AES_256_CBC_SHA256 */ | 1683 | // 0xC0,0x24, // TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - can't do SHA384 yet |
1358 | tls->key_size = AES256_KEYSIZE; | 1684 | 0xC0,0x27, // 6 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - ok: openssl s_server ... -cipher ECDHE-RSA-AES128-SHA256 |
1359 | tls->MAC_size = SHA256_OUTSIZE; | 1685 | // 0xC0,0x28, // TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - can't do SHA384 yet |
1686 | 0xC0,0x2B, // 7 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - ok: wget https://is.gd/ | ||
1687 | // 0xC0,0x2C, // TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - wget https://is.gd/: "TLS error from peer (alert code 20): bad MAC" | ||
1688 | 0xC0,0x2F, // 8 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - ok: openssl s_server ... -cipher ECDHE-RSA-AES128-GCM-SHA256 | ||
1689 | // 0xC0,0x30, // TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - openssl s_server ... -cipher ECDHE-RSA-AES256-GCM-SHA384: "decryption failed or bad record mac" | ||
1690 | //possibly these too: | ||
1691 | // 0xC0,0x35, // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA | ||
1692 | // 0xC0,0x36, // TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA | ||
1693 | // 0xC0,0x37, // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 | ||
1694 | // 0xC0,0x38, // TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 - can't do SHA384 yet | ||
1695 | 0x00,0x2F, // 9 TLS_RSA_WITH_AES_128_CBC_SHA - ok: openssl s_server ... -cipher AES128-SHA | ||
1696 | 0x00,0x35, //10 TLS_RSA_WITH_AES_256_CBC_SHA - ok: openssl s_server ... -cipher AES256-SHA | ||
1697 | 0x00,0x3C, //11 TLS_RSA_WITH_AES_128_CBC_SHA256 - ok: openssl s_server ... -cipher AES128-SHA256 | ||
1698 | 0x00,0x3D, //12 TLS_RSA_WITH_AES_256_CBC_SHA256 - ok: openssl s_server ... -cipher AES256-SHA256 | ||
1699 | 0x00,0x9C, //13 TLS_RSA_WITH_AES_128_GCM_SHA256 - ok: openssl s_server ... -cipher AES128-GCM-SHA256 | ||
1700 | // 0x00,0x9D, // TLS_RSA_WITH_AES_256_GCM_SHA384 - openssl s_server ... -cipher AES256-GCM-SHA384: "decryption failed or bad record mac" | ||
1701 | 0x00,0x3B, // TLS_RSA_WITH_NULL_SHA256 | ||
1702 | #endif | ||
1703 | cipherid1 = cipherid[1]; | ||
1704 | tls->cipher_id = 0x100 * cipherid[0] + cipherid1; | ||
1705 | tls->key_size = AES256_KEYSIZE; | ||
1706 | tls->MAC_size = SHA256_OUTSIZE; | ||
1707 | /*tls->IV_size = 0; - already is */ | ||
1708 | if (cipherid[0] == 0xC0) { | ||
1709 | /* All C0xx are ECDHE */ | ||
1710 | tls->flags |= NEED_EC_KEY; | ||
1711 | if (cipherid1 & 1) { | ||
1712 | /* Odd numbered C0xx use AES128 (even ones use AES256) */ | ||
1713 | tls->key_size = AES128_KEYSIZE; | ||
1714 | } | ||
1715 | if (cipherid1 <= 0x14) { | ||
1716 | tls->MAC_size = SHA1_OUTSIZE; | ||
1717 | } else | ||
1718 | if (cipherid1 >= 0x2B && cipherid1 <= 0x30) { | ||
1719 | /* C02B,2C,2F,30 are AES-GCM */ | ||
1720 | tls->flags |= ENCRYPTION_AESGCM; | ||
1721 | tls->MAC_size = 0; | ||
1722 | tls->IV_size = 4; | ||
1723 | } | ||
1724 | } else { | ||
1725 | /* All 00xx are RSA */ | ||
1726 | if (cipherid1 == 0x2F | ||
1727 | || cipherid1 == 0x3C | ||
1728 | || cipherid1 == 0x9C | ||
1729 | ) { | ||
1730 | tls->key_size = AES128_KEYSIZE; | ||
1731 | } | ||
1732 | if (cipherid1 <= 0x35) { | ||
1733 | tls->MAC_size = SHA1_OUTSIZE; | ||
1734 | } else | ||
1735 | if (cipherid1 == 0x9C /*|| cipherid1 == 0x9D*/) { | ||
1736 | /* 009C,9D are AES-GCM */ | ||
1737 | tls->flags |= ENCRYPTION_AESGCM; | ||
1738 | tls->MAC_size = 0; | ||
1739 | tls->IV_size = 4; | ||
1740 | } | ||
1360 | } | 1741 | } |
1742 | dbg("server chose cipher %04x\n", tls->cipher_id); | ||
1743 | dbg("key_size:%u MAC_size:%u IV_size:%u\n", tls->key_size, tls->MAC_size, tls->IV_size); | ||
1744 | |||
1361 | /* Handshake hash eventually destined to FINISHED record | 1745 | /* Handshake hash eventually destined to FINISHED record |
1362 | * is sha256 regardless of cipher | 1746 | * is sha256 regardless of cipher |
1363 | * (at least for all ciphers defined by RFC5246). | 1747 | * (at least for all ciphers defined by RFC5246). |
1364 | * It's not sha1 for AES_128_CBC_SHA - only MAC is sha1, not this hash. | 1748 | * It's not sha1 for AES_128_CBC_SHA - only MAC is sha1, not this hash. |
1365 | */ | 1749 | */ |
1750 | /* HANDSHAKE HASH: | ||
1366 | sha256_begin(&tls->hsd->handshake_hash_ctx); | 1751 | sha256_begin(&tls->hsd->handshake_hash_ctx); |
1367 | hash_handshake(tls, ">> client hello hash:%s", | 1752 | hash_handshake(tls, ">> client hello hash:%s", |
1368 | tls->hsd->saved_client_hello, tls->hsd->saved_client_hello_size | 1753 | tls->hsd->saved_client_hello, tls->hsd->saved_client_hello_size |
@@ -1370,6 +1755,7 @@ static void get_server_hello(tls_state_t *tls) | |||
1370 | hash_handshake(tls, "<< server hello hash:%s", | 1755 | hash_handshake(tls, "<< server hello hash:%s", |
1371 | tls->inbuf + RECHDR_LEN, len | 1756 | tls->inbuf + RECHDR_LEN, len |
1372 | ); | 1757 | ); |
1758 | */ | ||
1373 | } | 1759 | } |
1374 | 1760 | ||
1375 | static void get_server_cert(tls_state_t *tls) | 1761 | static void get_server_cert(tls_state_t *tls) |
@@ -1402,6 +1788,68 @@ static void get_server_cert(tls_state_t *tls) | |||
1402 | find_key_in_der_cert(tls, certbuf + 10, len); | 1788 | find_key_in_der_cert(tls, certbuf + 10, len); |
1403 | } | 1789 | } |
1404 | 1790 | ||
1791 | /* On input, len is known to be >= 4. | ||
1792 | * The record is known to be SERVER_KEY_EXCHANGE. | ||
1793 | */ | ||
1794 | static void process_server_key(tls_state_t *tls, int len) | ||
1795 | { | ||
1796 | struct record_hdr *xhdr; | ||
1797 | uint8_t *keybuf; | ||
1798 | int len1; | ||
1799 | uint32_t t32; | ||
1800 | |||
1801 | xhdr = (void*)tls->inbuf; | ||
1802 | keybuf = (void*)(xhdr + 1); | ||
1803 | //seen from is.gd: it selects curve_x25519: | ||
1804 | // 0c 00006e //SERVER_KEY_EXCHANGE, len | ||
1805 | // 03 //curve_type: named curve | ||
1806 | // 001d //curve_x25519 | ||
1807 | //server-chosen EC point, and then signed_params | ||
1808 | // (RFC 8422: "A hash of the params, with the signature | ||
1809 | // appropriate to that hash applied. The private key corresponding | ||
1810 | // to the certified public key in the server's Certificate message is | ||
1811 | // used for signing.") | ||
1812 | //follow. Format unclear/guessed: | ||
1813 | // 20 //eccPubKeyLen | ||
1814 | // 25511923d73b70dd2f60e66ba2f3fda31a9c25170963c7a3a972e481dbb2835d //eccPubKey (32bytes) | ||
1815 | // 0203 //hashSigAlg: 2:SHA1 (4:SHA256 5:SHA384 6:SHA512), 3:ECDSA (1:RSA) | ||
1816 | // 0046 //len (16bit) | ||
1817 | // 30 44 //SEQ, len | ||
1818 | // 02 20 //INTEGER, len | ||
1819 | // 2e18e7c2a9badd0a70cd3059a6ab114539b9f5163568911147386cd77ed7c412 //32bytes | ||
1820 | //this item ^^^^^ is sometimes 33 bytes (with all container sizes also +1) | ||
1821 | // 02 20 //INTEGER, len | ||
1822 | // 64523d6216cb94c43c9b20e377d8c52c55be6703fd6730a155930c705eaf3af6 //32bytes | ||
1823 | //same about this item ^^^^^ | ||
1824 | |||
1825 | //seen from ftp.openbsd.org | ||
1826 | //(which only accepts ECDHE-RSA-AESnnn-GCM-SHAnnn and ECDHE-RSA-CHACHA20-POLY1305 ciphers): | ||
1827 | // 0c 000228 //SERVER_KEY_EXCHANGE, len | ||
1828 | // 03 //curve_type: named curve | ||
1829 | // 001d //curve_x25519 | ||
1830 | // 20 //eccPubKeyLen | ||
1831 | // eef7a15c43b71a4c7eaa48a39369399cc4332e569ec90a83274cc92596705c1a //eccPubKey | ||
1832 | // 0401 //hashSigAlg: 4:SHA256, 1:RSA | ||
1833 | // 0200 //len | ||
1834 | // //0x200 bytes follow | ||
1835 | |||
1836 | /* Get and verify length */ | ||
1837 | len1 = get24be(keybuf + 1); | ||
1838 | if (len1 > len - 4) tls_error_die(tls); | ||
1839 | len = len1; | ||
1840 | if (len < (1+2+1+32)) tls_error_die(tls); | ||
1841 | keybuf += 4; | ||
1842 | |||
1843 | /* So far we only support curve_x25519 */ | ||
1844 | move_from_unaligned32(t32, keybuf); | ||
1845 | if (t32 != htonl(0x03001d20)) | ||
1846 | bb_error_msg_and_die("elliptic curve is not x25519"); | ||
1847 | |||
1848 | memcpy(tls->hsd->ecc_pub_key32, keybuf + 4, 32); | ||
1849 | tls->flags |= GOT_EC_KEY; | ||
1850 | dbg("got eccPubKey\n"); | ||
1851 | } | ||
1852 | |||
1405 | static void send_empty_client_cert(tls_state_t *tls) | 1853 | static void send_empty_client_cert(tls_state_t *tls) |
1406 | { | 1854 | { |
1407 | struct client_empty_cert { | 1855 | struct client_empty_cert { |
@@ -1411,12 +1859,14 @@ static void send_empty_client_cert(tls_state_t *tls) | |||
1411 | }; | 1859 | }; |
1412 | struct client_empty_cert *record; | 1860 | struct client_empty_cert *record; |
1413 | 1861 | ||
1414 | record = tls_get_outbuf(tls, sizeof(*record)); | 1862 | record = tls_get_zeroed_outbuf(tls, sizeof(*record)); |
1415 | //FIXME: can just memcpy a ready-made one. | 1863 | //fill_handshake_record_hdr(record, HANDSHAKE_CERTIFICATE, sizeof(*record)); |
1416 | fill_handshake_record_hdr(record, HANDSHAKE_CERTIFICATE, sizeof(*record)); | 1864 | //record->cert_chain_len24_hi = 0; |
1417 | record->cert_chain_len24_hi = 0; | 1865 | //record->cert_chain_len24_mid = 0; |
1418 | record->cert_chain_len24_mid = 0; | 1866 | //record->cert_chain_len24_lo = 0; |
1419 | record->cert_chain_len24_lo = 0; | 1867 | // same as above: |
1868 | record->type = HANDSHAKE_CERTIFICATE; | ||
1869 | record->len24_lo = 3; | ||
1420 | 1870 | ||
1421 | dbg(">> CERTIFICATE\n"); | 1871 | dbg(">> CERTIFICATE\n"); |
1422 | xwrite_and_update_handshake_hash(tls, sizeof(*record)); | 1872 | xwrite_and_update_handshake_hash(tls, sizeof(*record)); |
@@ -1427,36 +1877,72 @@ static void send_client_key_exchange(tls_state_t *tls) | |||
1427 | struct client_key_exchange { | 1877 | struct client_key_exchange { |
1428 | uint8_t type; | 1878 | uint8_t type; |
1429 | uint8_t len24_hi, len24_mid, len24_lo; | 1879 | uint8_t len24_hi, len24_mid, len24_lo; |
1430 | /* keylen16 exists for RSA (in TLS, not in SSL), but not for some other key types */ | 1880 | uint8_t key[2 + 4 * 1024]; // size?? |
1431 | uint8_t keylen16_hi, keylen16_lo; | ||
1432 | uint8_t key[4 * 1024]; // size?? | ||
1433 | }; | 1881 | }; |
1434 | //FIXME: better size estimate | 1882 | //FIXME: better size estimate |
1435 | struct client_key_exchange *record = tls_get_outbuf(tls, sizeof(*record)); | 1883 | struct client_key_exchange *record = tls_get_zeroed_outbuf(tls, sizeof(*record)); |
1436 | uint8_t rsa_premaster[RSA_PREMASTER_SIZE]; | 1884 | uint8_t rsa_premaster[RSA_PREMASTER_SIZE]; |
1885 | uint8_t x25519_premaster[CURVE25519_KEYSIZE]; | ||
1886 | uint8_t *premaster; | ||
1887 | int premaster_size; | ||
1437 | int len; | 1888 | int len; |
1438 | 1889 | ||
1439 | tls_get_random(rsa_premaster, sizeof(rsa_premaster)); | 1890 | if (!(tls->flags & NEED_EC_KEY)) { |
1440 | if (TLS_DEBUG_FIXED_SECRETS) | 1891 | /* RSA */ |
1441 | memset(rsa_premaster, 0x44, sizeof(rsa_premaster)); | 1892 | if (!(tls->flags & GOT_CERT_RSA_KEY_ALG)) |
1442 | // RFC 5246 | 1893 | bb_error_msg("server cert is not RSA"); |
1443 | // "Note: The version number in the PreMasterSecret is the version | 1894 | |
1444 | // offered by the client in the ClientHello.client_version, not the | 1895 | tls_get_random(rsa_premaster, sizeof(rsa_premaster)); |
1445 | // version negotiated for the connection." | 1896 | if (TLS_DEBUG_FIXED_SECRETS) |
1446 | rsa_premaster[0] = TLS_MAJ; | 1897 | memset(rsa_premaster, 0x44, sizeof(rsa_premaster)); |
1447 | rsa_premaster[1] = TLS_MIN; | 1898 | // RFC 5246 |
1448 | dump_hex("premaster:%s\n", rsa_premaster, sizeof(rsa_premaster)); | 1899 | // "Note: The version number in the PreMasterSecret is the version |
1449 | len = psRsaEncryptPub(/*pool:*/ NULL, | 1900 | // offered by the client in the ClientHello.client_version, not the |
1450 | /* psRsaKey_t* */ &tls->hsd->server_rsa_pub_key, | 1901 | // version negotiated for the connection." |
1451 | rsa_premaster, /*inlen:*/ sizeof(rsa_premaster), | 1902 | rsa_premaster[0] = TLS_MAJ; |
1452 | record->key, sizeof(record->key), | 1903 | rsa_premaster[1] = TLS_MIN; |
1453 | data_param_ignored | 1904 | dump_hex("premaster:%s\n", rsa_premaster, sizeof(rsa_premaster)); |
1454 | ); | 1905 | len = psRsaEncryptPub(/*pool:*/ NULL, |
1455 | record->keylen16_hi = len >> 8; | 1906 | /* psRsaKey_t* */ &tls->hsd->server_rsa_pub_key, |
1456 | record->keylen16_lo = len & 0xff; | 1907 | rsa_premaster, /*inlen:*/ sizeof(rsa_premaster), |
1457 | len += 2; | 1908 | record->key + 2, sizeof(record->key) - 2, |
1909 | data_param_ignored | ||
1910 | ); | ||
1911 | /* keylen16 exists for RSA (in TLS, not in SSL), but not for some other key types */ | ||
1912 | record->key[0] = len >> 8; | ||
1913 | record->key[1] = len & 0xff; | ||
1914 | len += 2; | ||
1915 | premaster = rsa_premaster; | ||
1916 | premaster_size = sizeof(rsa_premaster); | ||
1917 | } else { | ||
1918 | /* ECDHE */ | ||
1919 | static const uint8_t basepoint9[CURVE25519_KEYSIZE] = {9}; | ||
1920 | uint8_t privkey[CURVE25519_KEYSIZE]; //[32] | ||
1921 | |||
1922 | if (!(tls->flags & GOT_EC_KEY)) | ||
1923 | bb_error_msg("server did not provide EC key"); | ||
1924 | |||
1925 | /* Generate random private key, see RFC 7748 */ | ||
1926 | tls_get_random(privkey, sizeof(privkey)); | ||
1927 | privkey[0] &= 0xf8; | ||
1928 | privkey[CURVE25519_KEYSIZE-1] = ((privkey[CURVE25519_KEYSIZE-1] & 0x7f) | 0x40); | ||
1929 | |||
1930 | /* Compute public key */ | ||
1931 | curve25519(record->key + 1, privkey, basepoint9); | ||
1932 | |||
1933 | /* Compute premaster using peer's public key */ | ||
1934 | dbg("computing x25519_premaster\n"); | ||
1935 | curve25519(x25519_premaster, privkey, tls->hsd->ecc_pub_key32); | ||
1936 | |||
1937 | len = CURVE25519_KEYSIZE; | ||
1938 | record->key[0] = len; | ||
1939 | len++; | ||
1940 | premaster = x25519_premaster; | ||
1941 | premaster_size = sizeof(x25519_premaster); | ||
1942 | } | ||
1943 | |||
1458 | record->type = HANDSHAKE_CLIENT_KEY_EXCHANGE; | 1944 | record->type = HANDSHAKE_CLIENT_KEY_EXCHANGE; |
1459 | record->len24_hi = 0; | 1945 | /* record->len24_hi = 0; - already is */ |
1460 | record->len24_mid = len >> 8; | 1946 | record->len24_mid = len >> 8; |
1461 | record->len24_lo = len & 0xff; | 1947 | record->len24_lo = len & 0xff; |
1462 | len += 4; | 1948 | len += 4; |
@@ -1476,7 +1962,7 @@ static void send_client_key_exchange(tls_state_t *tls) | |||
1476 | // of the premaster secret will vary depending on key exchange method. | 1962 | // of the premaster secret will vary depending on key exchange method. |
1477 | prf_hmac_sha256(/*tls,*/ | 1963 | prf_hmac_sha256(/*tls,*/ |
1478 | tls->hsd->master_secret, sizeof(tls->hsd->master_secret), | 1964 | tls->hsd->master_secret, sizeof(tls->hsd->master_secret), |
1479 | rsa_premaster, sizeof(rsa_premaster), | 1965 | premaster, premaster_size, |
1480 | "master secret", | 1966 | "master secret", |
1481 | tls->hsd->client_and_server_rand32, sizeof(tls->hsd->client_and_server_rand32) | 1967 | tls->hsd->client_and_server_rand32, sizeof(tls->hsd->client_and_server_rand32) |
1482 | ); | 1968 | ); |
@@ -1523,23 +2009,38 @@ static void send_client_key_exchange(tls_state_t *tls) | |||
1523 | memcpy(&tmp64[32], &tls->hsd->client_and_server_rand32[0] , 32); | 2009 | memcpy(&tmp64[32], &tls->hsd->client_and_server_rand32[0] , 32); |
1524 | 2010 | ||
1525 | prf_hmac_sha256(/*tls,*/ | 2011 | prf_hmac_sha256(/*tls,*/ |
1526 | tls->client_write_MAC_key, 2 * (tls->MAC_size + tls->key_size), | 2012 | tls->client_write_MAC_key, 2 * (tls->MAC_size + tls->key_size + tls->IV_size), |
1527 | // also fills: | 2013 | // also fills: |
1528 | // server_write_MAC_key[] | 2014 | // server_write_MAC_key[] |
1529 | // client_write_key[] | 2015 | // client_write_key[] |
1530 | // server_write_key[] | 2016 | // server_write_key[] |
2017 | // client_write_IV[] | ||
2018 | // server_write_IV[] | ||
1531 | tls->hsd->master_secret, sizeof(tls->hsd->master_secret), | 2019 | tls->hsd->master_secret, sizeof(tls->hsd->master_secret), |
1532 | "key expansion", | 2020 | "key expansion", |
1533 | tmp64, 64 | 2021 | tmp64, 64 |
1534 | ); | 2022 | ); |
1535 | tls->client_write_key = tls->client_write_MAC_key + (2 * tls->MAC_size); | 2023 | tls->client_write_key = tls->client_write_MAC_key + (2 * tls->MAC_size); |
1536 | tls->server_write_key = tls->client_write_key + tls->key_size; | 2024 | tls->server_write_key = tls->client_write_key + tls->key_size; |
2025 | tls->client_write_IV = tls->server_write_key + tls->key_size; | ||
2026 | tls->server_write_IV = tls->client_write_IV + tls->IV_size; | ||
1537 | dump_hex("client_write_MAC_key:%s\n", | 2027 | dump_hex("client_write_MAC_key:%s\n", |
1538 | tls->client_write_MAC_key, tls->MAC_size | 2028 | tls->client_write_MAC_key, tls->MAC_size |
1539 | ); | 2029 | ); |
1540 | dump_hex("client_write_key:%s\n", | 2030 | dump_hex("client_write_key:%s\n", |
1541 | tls->client_write_key, tls->key_size | 2031 | tls->client_write_key, tls->key_size |
1542 | ); | 2032 | ); |
2033 | dump_hex("client_write_IV:%s\n", | ||
2034 | tls->client_write_IV, tls->IV_size | ||
2035 | ); | ||
2036 | |||
2037 | aes_setkey(&tls->aes_decrypt, tls->server_write_key, tls->key_size); | ||
2038 | aes_setkey(&tls->aes_encrypt, tls->client_write_key, tls->key_size); | ||
2039 | { | ||
2040 | uint8_t iv[AES_BLOCK_SIZE]; | ||
2041 | memset(iv, 0, AES_BLOCK_SIZE); | ||
2042 | aes_encrypt_one_block(&tls->aes_encrypt, iv, tls->H); | ||
2043 | } | ||
1543 | } | 2044 | } |
1544 | } | 2045 | } |
1545 | 2046 | ||
@@ -1604,7 +2105,8 @@ static void send_client_finished(tls_state_t *tls) | |||
1604 | 2105 | ||
1605 | fill_handshake_record_hdr(record, HANDSHAKE_FINISHED, sizeof(*record)); | 2106 | fill_handshake_record_hdr(record, HANDSHAKE_FINISHED, sizeof(*record)); |
1606 | 2107 | ||
1607 | len = get_handshake_hash(tls, handshake_hash); | 2108 | len = sha_end(&tls->hsd->handshake_hash_ctx, handshake_hash); |
2109 | |||
1608 | prf_hmac_sha256(/*tls,*/ | 2110 | prf_hmac_sha256(/*tls,*/ |
1609 | record->prf_result, sizeof(record->prf_result), | 2111 | record->prf_result, sizeof(record->prf_result), |
1610 | tls->hsd->master_secret, sizeof(tls->hsd->master_secret), | 2112 | tls->hsd->master_secret, sizeof(tls->hsd->master_secret), |
@@ -1663,8 +2165,19 @@ void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni) | |||
1663 | //SvKey len=455^ | 2165 | //SvKey len=455^ |
1664 | // with TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: 461 bytes: | 2166 | // with TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: 461 bytes: |
1665 | // 0c 00|01|c9 03|00|17|41|04|cd|9b|b4|29|1f|f6|b0|c2|84|82|7f|29|6a|47|4e|ec|87|0b|c1|9c|69|e1|f8|c6|d0|53|e9|27|90|a5|c8|02|15|75... | 2167 | // 0c 00|01|c9 03|00|17|41|04|cd|9b|b4|29|1f|f6|b0|c2|84|82|7f|29|6a|47|4e|ec|87|0b|c1|9c|69|e1|f8|c6|d0|53|e9|27|90|a5|c8|02|15|75... |
2168 | // | ||
2169 | // RFC 8422 5.4. Server Key Exchange | ||
2170 | // This message is sent when using the ECDHE_ECDSA, ECDHE_RSA, and | ||
2171 | // ECDH_anon key exchange algorithms. | ||
2172 | // This message is used to convey the server's ephemeral ECDH public key | ||
2173 | // (and the corresponding elliptic curve domain parameters) to the | ||
2174 | // client. | ||
1666 | dbg("<< SERVER_KEY_EXCHANGE len:%u\n", len); | 2175 | dbg("<< SERVER_KEY_EXCHANGE len:%u\n", len); |
1667 | //probably need to save it | 2176 | dump_raw_in("<< %s\n", tls->inbuf, RECHDR_LEN + len); |
2177 | if (tls->flags & NEED_EC_KEY) | ||
2178 | process_server_key(tls, len); | ||
2179 | |||
2180 | // read next handshake block | ||
1668 | len = tls_xread_handshake_block(tls, 4); | 2181 | len = tls_xread_handshake_block(tls, 4); |
1669 | } | 2182 | } |
1670 | 2183 | ||
@@ -1698,7 +2211,7 @@ void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni) | |||
1698 | send_change_cipher_spec(tls); | 2211 | send_change_cipher_spec(tls); |
1699 | /* from now on we should send encrypted */ | 2212 | /* from now on we should send encrypted */ |
1700 | /* tls->write_seq64_be = 0; - already is */ | 2213 | /* tls->write_seq64_be = 0; - already is */ |
1701 | tls->encrypt_on_write = 1; | 2214 | tls->flags |= ENCRYPT_ON_WRITE; |
1702 | 2215 | ||
1703 | send_client_finished(tls); | 2216 | send_client_finished(tls); |
1704 | 2217 | ||
@@ -1707,18 +2220,22 @@ void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni) | |||
1707 | if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0) | 2220 | if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0) |
1708 | bad_record_die(tls, "switch to encrypted traffic", len); | 2221 | bad_record_die(tls, "switch to encrypted traffic", len); |
1709 | dbg("<< CHANGE_CIPHER_SPEC\n"); | 2222 | dbg("<< CHANGE_CIPHER_SPEC\n"); |
1710 | if (CIPHER_ID1 == TLS_RSA_WITH_NULL_SHA256 | 2223 | |
2224 | if (ALLOW_RSA_NULL_SHA256 | ||
1711 | && tls->cipher_id == TLS_RSA_WITH_NULL_SHA256 | 2225 | && tls->cipher_id == TLS_RSA_WITH_NULL_SHA256 |
1712 | ) { | 2226 | ) { |
1713 | tls->min_encrypted_len_on_read = tls->MAC_size; | 2227 | tls->min_encrypted_len_on_read = tls->MAC_size; |
1714 | } else { | 2228 | } else |
1715 | unsigned mac_blocks = (unsigned)(tls->MAC_size + AES_BLOCKSIZE-1) / AES_BLOCKSIZE; | 2229 | if (!(tls->flags & ENCRYPTION_AESGCM)) { |
2230 | unsigned mac_blocks = (unsigned)(tls->MAC_size + AES_BLOCK_SIZE-1) / AES_BLOCK_SIZE; | ||
1716 | /* all incoming packets now should be encrypted and have | 2231 | /* all incoming packets now should be encrypted and have |
1717 | * at least IV + (MAC padded to blocksize): | 2232 | * at least IV + (MAC padded to blocksize): |
1718 | */ | 2233 | */ |
1719 | tls->min_encrypted_len_on_read = AES_BLOCKSIZE + (mac_blocks * AES_BLOCKSIZE); | 2234 | tls->min_encrypted_len_on_read = AES_BLOCK_SIZE + (mac_blocks * AES_BLOCK_SIZE); |
1720 | dbg("min_encrypted_len_on_read: %u", tls->min_encrypted_len_on_read); | 2235 | } else { |
2236 | tls->min_encrypted_len_on_read = 8 + AES_BLOCK_SIZE; | ||
1721 | } | 2237 | } |
2238 | dbg("min_encrypted_len_on_read: %u\n", tls->min_encrypted_len_on_read); | ||
1722 | 2239 | ||
1723 | /* Get (encrypted) FINISHED from the server */ | 2240 | /* Get (encrypted) FINISHED from the server */ |
1724 | len = tls_xread_record(tls, "'server finished'"); | 2241 | len = tls_xread_record(tls, "'server finished'"); |
@@ -1728,6 +2245,7 @@ void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni) | |||
1728 | /* application data can be sent/received */ | 2245 | /* application data can be sent/received */ |
1729 | 2246 | ||
1730 | /* free handshake data */ | 2247 | /* free handshake data */ |
2248 | psRsaKey_clear(&tls->hsd->server_rsa_pub_key); | ||
1731 | // if (PARANOIA) | 2249 | // if (PARANOIA) |
1732 | // memset(tls->hsd, 0, tls->hsd->hsd_size); | 2250 | // memset(tls->hsd, 0, tls->hsd->hsd_size); |
1733 | free(tls->hsd); | 2251 | free(tls->hsd); |
@@ -1742,12 +2260,12 @@ static void tls_xwrite(tls_state_t *tls, int len) | |||
1742 | 2260 | ||
1743 | // To run a test server using openssl: | 2261 | // To run a test server using openssl: |
1744 | // openssl req -x509 -newkey rsa:$((4096/4*3)) -keyout key.pem -out server.pem -nodes -days 99999 -subj '/CN=localhost' | 2262 | // openssl req -x509 -newkey rsa:$((4096/4*3)) -keyout key.pem -out server.pem -nodes -days 99999 -subj '/CN=localhost' |
1745 | // openssl s_server -key key.pem -cert server.pem -debug -tls1_2 -no_tls1 -no_tls1_1 | 2263 | // openssl s_server -key key.pem -cert server.pem -debug -tls1_2 |
1746 | // | 2264 | // |
1747 | // Unencryped SHA256 example: | 2265 | // Unencryped SHA256 example: |
1748 | // openssl req -x509 -newkey rsa:$((4096/4*3)) -keyout key.pem -out server.pem -nodes -days 99999 -subj '/CN=localhost' | 2266 | // openssl req -x509 -newkey rsa:$((4096/4*3)) -keyout key.pem -out server.pem -nodes -days 99999 -subj '/CN=localhost' |
1749 | // openssl s_server -key key.pem -cert server.pem -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL | 2267 | // openssl s_server -key key.pem -cert server.pem -debug -tls1_2 -cipher NULL |
1750 | // openssl s_client -connect 127.0.0.1:4433 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL-SHA256 | 2268 | // openssl s_client -connect 127.0.0.1:4433 -debug -tls1_2 -cipher NULL-SHA256 |
1751 | 2269 | ||
1752 | void FAST_FUNC tls_run_copy_loop(tls_state_t *tls, unsigned flags) | 2270 | void FAST_FUNC tls_run_copy_loop(tls_state_t *tls, unsigned flags) |
1753 | { | 2271 | { |
diff --git a/networking/tls.h b/networking/tls.h index d487f3810..494ed78c4 100644 --- a/networking/tls.h +++ b/networking/tls.h | |||
@@ -78,7 +78,14 @@ typedef int16_t int16; | |||
78 | #define PUBKEY_TYPE 0x01 | 78 | #define PUBKEY_TYPE 0x01 |
79 | #define PRIVKEY_TYPE 0x02 | 79 | #define PRIVKEY_TYPE 0x02 |
80 | 80 | ||
81 | void tls_get_random(void *buf, unsigned len); | 81 | #define AES_BLOCK_SIZE 16 |
82 | |||
83 | void tls_get_random(void *buf, unsigned len) FAST_FUNC; | ||
84 | |||
85 | void xorbuf(void* buf, const void* mask, unsigned count) FAST_FUNC; | ||
86 | |||
87 | #define ALIGNED_long ALIGNED(sizeof(long)) | ||
88 | void xorbuf_aligned_AES_BLOCK_SIZE(void* buf, const void* mask) FAST_FUNC; | ||
82 | 89 | ||
83 | #define matrixCryptoGetPrngData(buf, len, userPtr) (tls_get_random(buf, len), PS_SUCCESS) | 90 | #define matrixCryptoGetPrngData(buf, len, userPtr) (tls_get_random(buf, len), PS_SUCCESS) |
84 | 91 | ||
@@ -94,6 +101,8 @@ void tls_get_random(void *buf, unsigned len); | |||
94 | 101 | ||
95 | 102 | ||
96 | #include "tls_pstm.h" | 103 | #include "tls_pstm.h" |
97 | #include "tls_rsa.h" | ||
98 | #include "tls_symmetric.h" | 104 | #include "tls_symmetric.h" |
99 | #include "tls_aes.h" | 105 | #include "tls_aes.h" |
106 | #include "tls_aesgcm.h" | ||
107 | #include "tls_rsa.h" | ||
108 | #include "tls_fe.h" | ||
diff --git a/networking/tls_aes.c b/networking/tls_aes.c index c137442e9..cf6b5fe3d 100644 --- a/networking/tls_aes.c +++ b/networking/tls_aes.c | |||
@@ -326,8 +326,11 @@ static void InvMixColumns(unsigned astate[16]) | |||
326 | } | 326 | } |
327 | } | 327 | } |
328 | 328 | ||
329 | static void aes_encrypt_1(unsigned astate[16], unsigned rounds, const uint32_t *RoundKey) | 329 | static void aes_encrypt_1(struct tls_aes *aes, unsigned astate[16]) |
330 | { | 330 | { |
331 | unsigned rounds = aes->rounds; | ||
332 | const uint32_t *RoundKey = aes->key; | ||
333 | |||
331 | for (;;) { | 334 | for (;;) { |
332 | AddRoundKey(astate, RoundKey); | 335 | AddRoundKey(astate, RoundKey); |
333 | RoundKey += 4; | 336 | RoundKey += 4; |
@@ -340,8 +343,12 @@ static void aes_encrypt_1(unsigned astate[16], unsigned rounds, const uint32_t * | |||
340 | AddRoundKey(astate, RoundKey); | 343 | AddRoundKey(astate, RoundKey); |
341 | } | 344 | } |
342 | 345 | ||
343 | #if 0 // UNUSED | 346 | void FAST_FUNC aes_setkey(struct tls_aes *aes, const void *key, unsigned key_len) |
344 | static void aes_encrypt_one_block(unsigned rounds, const uint32_t *RoundKey, const void *data, void *dst) | 347 | { |
348 | aes->rounds = KeyExpansion(aes->key, key, key_len); | ||
349 | } | ||
350 | |||
351 | void FAST_FUNC aes_encrypt_one_block(struct tls_aes *aes, const void *data, void *dst) | ||
345 | { | 352 | { |
346 | unsigned astate[16]; | 353 | unsigned astate[16]; |
347 | unsigned i; | 354 | unsigned i; |
@@ -351,23 +358,19 @@ static void aes_encrypt_one_block(unsigned rounds, const uint32_t *RoundKey, con | |||
351 | 358 | ||
352 | for (i = 0; i < 16; i++) | 359 | for (i = 0; i < 16; i++) |
353 | astate[i] = pt[i]; | 360 | astate[i] = pt[i]; |
354 | aes_encrypt_1(astate, rounds, RoundKey); | 361 | aes_encrypt_1(aes, astate); |
355 | for (i = 0; i < 16; i++) | 362 | for (i = 0; i < 16; i++) |
356 | ct[i] = astate[i]; | 363 | ct[i] = astate[i]; |
357 | } | 364 | } |
358 | #endif | ||
359 | 365 | ||
360 | void aes_cbc_encrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst) | 366 | void FAST_FUNC aes_cbc_encrypt(struct tls_aes *aes, void *iv, const void *data, size_t len, void *dst) |
361 | { | 367 | { |
362 | uint32_t RoundKey[60]; | ||
363 | uint8_t iv2[16]; | 368 | uint8_t iv2[16]; |
364 | unsigned rounds; | ||
365 | 369 | ||
366 | const uint8_t *pt = data; | 370 | const uint8_t *pt = data; |
367 | uint8_t *ct = dst; | 371 | uint8_t *ct = dst; |
368 | 372 | ||
369 | memcpy(iv2, iv, 16); | 373 | memcpy(iv2, iv, 16); |
370 | rounds = KeyExpansion(RoundKey, key, klen); | ||
371 | while (len > 0) { | 374 | while (len > 0) { |
372 | { | 375 | { |
373 | /* almost aes_encrypt_one_block(rounds, RoundKey, pt, ct); | 376 | /* almost aes_encrypt_one_block(rounds, RoundKey, pt, ct); |
@@ -378,7 +381,7 @@ void aes_cbc_encrypt(const void *key, int klen, void *iv, const void *data, size | |||
378 | unsigned astate[16]; | 381 | unsigned astate[16]; |
379 | for (i = 0; i < 16; i++) | 382 | for (i = 0; i < 16; i++) |
380 | astate[i] = pt[i] ^ iv2[i]; | 383 | astate[i] = pt[i] ^ iv2[i]; |
381 | aes_encrypt_1(astate, rounds, RoundKey); | 384 | aes_encrypt_1(aes, astate); |
382 | for (i = 0; i < 16; i++) | 385 | for (i = 0; i < 16; i++) |
383 | iv2[i] = ct[i] = astate[i]; | 386 | iv2[i] = ct[i] = astate[i]; |
384 | } | 387 | } |
@@ -388,8 +391,11 @@ void aes_cbc_encrypt(const void *key, int klen, void *iv, const void *data, size | |||
388 | } | 391 | } |
389 | } | 392 | } |
390 | 393 | ||
391 | static void aes_decrypt_1(unsigned astate[16], unsigned rounds, const uint32_t *RoundKey) | 394 | static void aes_decrypt_1(struct tls_aes *aes, unsigned astate[16]) |
392 | { | 395 | { |
396 | unsigned rounds = aes->rounds; | ||
397 | const uint32_t *RoundKey = aes->key; | ||
398 | |||
393 | RoundKey += rounds * 4; | 399 | RoundKey += rounds * 4; |
394 | AddRoundKey(astate, RoundKey); | 400 | AddRoundKey(astate, RoundKey); |
395 | for (;;) { | 401 | for (;;) { |
@@ -404,8 +410,10 @@ static void aes_decrypt_1(unsigned astate[16], unsigned rounds, const uint32_t * | |||
404 | } | 410 | } |
405 | 411 | ||
406 | #if 0 //UNUSED | 412 | #if 0 //UNUSED |
407 | static void aes_decrypt_one_block(unsigned rounds, const uint32_t *RoundKey, const void *data, void *dst) | 413 | static void aes_decrypt_one_block(struct tls_aes *aes, const void *data, void *dst) |
408 | { | 414 | { |
415 | unsigned rounds = aes->rounds; | ||
416 | const uint32_t *RoundKey = aes->key; | ||
409 | unsigned astate[16]; | 417 | unsigned astate[16]; |
410 | unsigned i; | 418 | unsigned i; |
411 | 419 | ||
@@ -414,25 +422,22 @@ static void aes_decrypt_one_block(unsigned rounds, const uint32_t *RoundKey, con | |||
414 | 422 | ||
415 | for (i = 0; i < 16; i++) | 423 | for (i = 0; i < 16; i++) |
416 | astate[i] = ct[i]; | 424 | astate[i] = ct[i]; |
417 | aes_decrypt_1(astate, rounds, RoundKey); | 425 | aes_decrypt_1(aes, astate); |
418 | for (i = 0; i < 16; i++) | 426 | for (i = 0; i < 16; i++) |
419 | pt[i] = astate[i]; | 427 | pt[i] = astate[i]; |
420 | } | 428 | } |
421 | #endif | 429 | #endif |
422 | 430 | ||
423 | void aes_cbc_decrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst) | 431 | void FAST_FUNC aes_cbc_decrypt(struct tls_aes *aes, void *iv, const void *data, size_t len, void *dst) |
424 | { | 432 | { |
425 | uint32_t RoundKey[60]; | ||
426 | uint8_t iv2[16]; | 433 | uint8_t iv2[16]; |
427 | uint8_t iv3[16]; | 434 | uint8_t iv3[16]; |
428 | unsigned rounds; | ||
429 | uint8_t *ivbuf; | 435 | uint8_t *ivbuf; |
430 | uint8_t *ivnext; | 436 | uint8_t *ivnext; |
431 | 437 | ||
432 | const uint8_t *ct = data; | 438 | const uint8_t *ct = data; |
433 | uint8_t *pt = dst; | 439 | uint8_t *pt = dst; |
434 | 440 | ||
435 | rounds = KeyExpansion(RoundKey, key, klen); | ||
436 | ivbuf = memcpy(iv2, iv, 16); | 441 | ivbuf = memcpy(iv2, iv, 16); |
437 | while (len) { | 442 | while (len) { |
438 | ivnext = (ivbuf==iv2) ? iv3 : iv2; | 443 | ivnext = (ivbuf==iv2) ? iv3 : iv2; |
@@ -444,7 +449,7 @@ void aes_cbc_decrypt(const void *key, int klen, void *iv, const void *data, size | |||
444 | unsigned astate[16]; | 449 | unsigned astate[16]; |
445 | for (i = 0; i < 16; i++) | 450 | for (i = 0; i < 16; i++) |
446 | ivnext[i] = astate[i] = ct[i]; | 451 | ivnext[i] = astate[i] = ct[i]; |
447 | aes_decrypt_1(astate, rounds, RoundKey); | 452 | aes_decrypt_1(aes, astate); |
448 | for (i = 0; i < 16; i++) | 453 | for (i = 0; i < 16; i++) |
449 | pt[i] = astate[i] ^ ivbuf[i]; | 454 | pt[i] = astate[i] ^ ivbuf[i]; |
450 | } | 455 | } |
diff --git a/networking/tls_aes.h b/networking/tls_aes.h index c6791866a..e9e3721f1 100644 --- a/networking/tls_aes.h +++ b/networking/tls_aes.h | |||
@@ -6,5 +6,9 @@ | |||
6 | * Selected few declarations for AES. | 6 | * Selected few declarations for AES. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | void aes_cbc_encrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst); | 9 | void aes_setkey(struct tls_aes *aes, const void *key, unsigned key_len) FAST_FUNC; |
10 | void aes_cbc_decrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst); | 10 | |
11 | void aes_encrypt_one_block(struct tls_aes *aes, const void *data, void *dst) FAST_FUNC; | ||
12 | |||
13 | void aes_cbc_encrypt(struct tls_aes *aes, void *iv, const void *data, size_t len, void *dst) FAST_FUNC; | ||
14 | void aes_cbc_decrypt(struct tls_aes *aes, void *iv, const void *data, size_t len, void *dst) FAST_FUNC; | ||
diff --git a/networking/tls_aesgcm.c b/networking/tls_aesgcm.c new file mode 100644 index 000000000..688df85fb --- /dev/null +++ b/networking/tls_aesgcm.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2018 Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | |||
7 | #include "tls.h" | ||
8 | |||
9 | typedef uint8_t byte; | ||
10 | typedef uint32_t word32; | ||
11 | #define XMEMSET memset | ||
12 | #define XMEMCPY memcpy | ||
13 | |||
14 | /* from wolfssl-3.15.3/wolfcrypt/src/aes.c */ | ||
15 | |||
16 | static ALWAYS_INLINE void FlattenSzInBits(byte* buf, word32 sz) | ||
17 | { | ||
18 | /* Multiply the sz by 8 */ | ||
19 | //bbox: these sizes are never even close to 2^32/8 | ||
20 | // word32 szHi = (sz >> (8*sizeof(sz) - 3)); | ||
21 | sz <<= 3; | ||
22 | |||
23 | /* copy over the words of the sz into the destination buffer */ | ||
24 | // buf[0] = (szHi >> 24) & 0xff; | ||
25 | // buf[1] = (szHi >> 16) & 0xff; | ||
26 | // buf[2] = (szHi >> 8) & 0xff; | ||
27 | // buf[3] = szHi & 0xff; | ||
28 | *(uint32_t*)(buf + 0) = 0; | ||
29 | // buf[4] = (sz >> 24) & 0xff; | ||
30 | // buf[5] = (sz >> 16) & 0xff; | ||
31 | // buf[6] = (sz >> 8) & 0xff; | ||
32 | // buf[7] = sz & 0xff; | ||
33 | *(uint32_t*)(buf + 4) = SWAP_BE32(sz); | ||
34 | } | ||
35 | |||
36 | static void RIGHTSHIFTX(byte* x) | ||
37 | { | ||
38 | int i; | ||
39 | int carryOut = 0; | ||
40 | int carryIn = 0; | ||
41 | int borrow = x[15] & 0x01; | ||
42 | |||
43 | for (i = 0; i < AES_BLOCK_SIZE; i++) { | ||
44 | carryOut = x[i] & 0x01; | ||
45 | x[i] = (x[i] >> 1) | (carryIn ? 0x80 : 0); | ||
46 | carryIn = carryOut; | ||
47 | } | ||
48 | if (borrow) x[0] ^= 0xE1; | ||
49 | } | ||
50 | |||
51 | static void GMULT(byte* X, byte* Y) | ||
52 | { | ||
53 | byte Z[AES_BLOCK_SIZE] ALIGNED_long; | ||
54 | byte V[AES_BLOCK_SIZE] ALIGNED_long; | ||
55 | int i, j; | ||
56 | |||
57 | XMEMSET(Z, 0, AES_BLOCK_SIZE); | ||
58 | XMEMCPY(V, X, AES_BLOCK_SIZE); | ||
59 | for (i = 0; i < AES_BLOCK_SIZE; i++) | ||
60 | { | ||
61 | byte y = Y[i]; | ||
62 | for (j = 0; j < 8; j++) | ||
63 | { | ||
64 | if (y & 0x80) { | ||
65 | xorbuf_aligned_AES_BLOCK_SIZE(Z, V); | ||
66 | } | ||
67 | |||
68 | RIGHTSHIFTX(V); | ||
69 | y = y << 1; | ||
70 | } | ||
71 | } | ||
72 | XMEMCPY(X, Z, AES_BLOCK_SIZE); | ||
73 | } | ||
74 | |||
75 | //bbox: | ||
76 | // for TLS AES-GCM, a (which is AAD) is always 13 bytes long, and bbox code provides | ||
77 | // extra 3 zeroed bytes, making it a[16], or a[AES_BLOCK_SIZE]. | ||
78 | // Resulting auth tag in s[] is also always AES_BLOCK_SIZE bytes. | ||
79 | // | ||
80 | // This allows some simplifications. | ||
81 | #define aSz 13 | ||
82 | #define sSz AES_BLOCK_SIZE | ||
83 | void FAST_FUNC aesgcm_GHASH(byte* h, | ||
84 | const byte* a, //unsigned aSz, | ||
85 | const byte* c, unsigned cSz, | ||
86 | byte* s //, unsigned sSz | ||
87 | ) | ||
88 | { | ||
89 | byte x[AES_BLOCK_SIZE] ALIGNED_long; | ||
90 | // byte scratch[AES_BLOCK_SIZE] ALIGNED_long; | ||
91 | unsigned blocks, partial; | ||
92 | //was: byte* h = aes->H; | ||
93 | |||
94 | //XMEMSET(x, 0, AES_BLOCK_SIZE); | ||
95 | |||
96 | /* Hash in A, the Additional Authentication Data */ | ||
97 | // if (aSz != 0 && a != NULL) { | ||
98 | // blocks = aSz / AES_BLOCK_SIZE; | ||
99 | // partial = aSz % AES_BLOCK_SIZE; | ||
100 | // while (blocks--) { | ||
101 | //xorbuf(x, a, AES_BLOCK_SIZE); | ||
102 | XMEMCPY(x, a, AES_BLOCK_SIZE);// memcpy(x,a) = memset(x,0)+xorbuf(x,a) | ||
103 | GMULT(x, h); | ||
104 | // a += AES_BLOCK_SIZE; | ||
105 | // } | ||
106 | // if (partial != 0) { | ||
107 | // XMEMSET(scratch, 0, AES_BLOCK_SIZE); | ||
108 | // XMEMCPY(scratch, a, partial); | ||
109 | // xorbuf(x, scratch, AES_BLOCK_SIZE); | ||
110 | // GMULT(x, h); | ||
111 | // } | ||
112 | // } | ||
113 | |||
114 | /* Hash in C, the Ciphertext */ | ||
115 | if (cSz != 0 /*&& c != NULL*/) { | ||
116 | blocks = cSz / AES_BLOCK_SIZE; | ||
117 | partial = cSz % AES_BLOCK_SIZE; | ||
118 | while (blocks--) { | ||
119 | if (BB_UNALIGNED_MEMACCESS_OK) // c is not guaranteed to be aligned | ||
120 | xorbuf_aligned_AES_BLOCK_SIZE(x, c); | ||
121 | else | ||
122 | xorbuf(x, c, AES_BLOCK_SIZE); | ||
123 | GMULT(x, h); | ||
124 | c += AES_BLOCK_SIZE; | ||
125 | } | ||
126 | if (partial != 0) { | ||
127 | //XMEMSET(scratch, 0, AES_BLOCK_SIZE); | ||
128 | //XMEMCPY(scratch, c, partial); | ||
129 | //xorbuf(x, scratch, AES_BLOCK_SIZE); | ||
130 | xorbuf(x, c, partial);//same result as above | ||
131 | GMULT(x, h); | ||
132 | } | ||
133 | } | ||
134 | |||
135 | /* Hash in the lengths of A and C in bits */ | ||
136 | //FlattenSzInBits(&scratch[0], aSz); | ||
137 | //FlattenSzInBits(&scratch[8], cSz); | ||
138 | //xorbuf_aligned_AES_BLOCK_SIZE(x, scratch); | ||
139 | // simpler: | ||
140 | #define P32(v) ((uint32_t*)v) | ||
141 | //P32(x)[0] ^= 0; | ||
142 | P32(x)[1] ^= SWAP_BE32(aSz * 8); | ||
143 | //P32(x)[2] ^= 0; | ||
144 | P32(x)[3] ^= SWAP_BE32(cSz * 8); | ||
145 | #undef P32 | ||
146 | |||
147 | GMULT(x, h); | ||
148 | |||
149 | /* Copy the result into s. */ | ||
150 | XMEMCPY(s, x, sSz); | ||
151 | } | ||
diff --git a/networking/tls_aesgcm.h b/networking/tls_aesgcm.h new file mode 100644 index 000000000..d7e672e6e --- /dev/null +++ b/networking/tls_aesgcm.h | |||
@@ -0,0 +1,11 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2018 Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | |||
7 | void aesgcm_GHASH(uint8_t* h, | ||
8 | const uint8_t* a, //unsigned aSz, | ||
9 | const uint8_t* c, unsigned cSz, | ||
10 | uint8_t* s //, unsigned sSz | ||
11 | ) FAST_FUNC; | ||
diff --git a/networking/tls_fe.c b/networking/tls_fe.c new file mode 100644 index 000000000..f235082f5 --- /dev/null +++ b/networking/tls_fe.c | |||
@@ -0,0 +1,611 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2018 Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | #include "tls.h" | ||
7 | |||
8 | typedef uint8_t byte; | ||
9 | typedef uint16_t word16; | ||
10 | typedef uint32_t word32; | ||
11 | #define XMEMSET memset | ||
12 | |||
13 | #define F25519_SIZE CURVE25519_KEYSIZE | ||
14 | |||
15 | /* The code below is taken from wolfssl-3.15.3/wolfcrypt/src/fe_low_mem.c | ||
16 | * Header comment is kept intact: | ||
17 | */ | ||
18 | |||
19 | /* fe_low_mem.c | ||
20 | * | ||
21 | * Copyright (C) 2006-2017 wolfSSL Inc. | ||
22 | * | ||
23 | * This file is part of wolfSSL. | ||
24 | * | ||
25 | * wolfSSL is free software; you can redistribute it and/or modify | ||
26 | * it under the terms of the GNU General Public License as published by | ||
27 | * the Free Software Foundation; either version 2 of the License, or | ||
28 | * (at your option) any later version. | ||
29 | * | ||
30 | * wolfSSL is distributed in the hope that it will be useful, | ||
31 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
32 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
33 | * GNU General Public License for more details. | ||
34 | * | ||
35 | * You should have received a copy of the GNU General Public License | ||
36 | * along with this program; if not, write to the Free Software | ||
37 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA | ||
38 | */ | ||
39 | |||
40 | |||
41 | /* Based from Daniel Beer's public domain work. */ | ||
42 | |||
43 | #if 0 //UNUSED | ||
44 | static void fprime_copy(byte *x, const byte *a) | ||
45 | { | ||
46 | int i; | ||
47 | for (i = 0; i < F25519_SIZE; i++) | ||
48 | x[i] = a[i]; | ||
49 | } | ||
50 | #endif | ||
51 | |||
52 | static void lm_copy(byte* x, const byte* a) | ||
53 | { | ||
54 | int i; | ||
55 | for (i = 0; i < F25519_SIZE; i++) | ||
56 | x[i] = a[i]; | ||
57 | } | ||
58 | |||
59 | #if 0 //UNUSED | ||
60 | static void fprime_select(byte *dst, const byte *zero, const byte *one, byte condition) | ||
61 | { | ||
62 | const byte mask = -condition; | ||
63 | int i; | ||
64 | |||
65 | for (i = 0; i < F25519_SIZE; i++) | ||
66 | dst[i] = zero[i] ^ (mask & (one[i] ^ zero[i])); | ||
67 | } | ||
68 | #endif | ||
69 | |||
70 | static void fe_select(byte *dst, | ||
71 | const byte *zero, const byte *one, | ||
72 | byte condition) | ||
73 | { | ||
74 | const byte mask = -condition; | ||
75 | int i; | ||
76 | |||
77 | for (i = 0; i < F25519_SIZE; i++) | ||
78 | dst[i] = zero[i] ^ (mask & (one[i] ^ zero[i])); | ||
79 | } | ||
80 | |||
81 | #if 0 //UNUSED | ||
82 | static void raw_add(byte *x, const byte *p) | ||
83 | { | ||
84 | word16 c = 0; | ||
85 | int i; | ||
86 | |||
87 | for (i = 0; i < F25519_SIZE; i++) { | ||
88 | c += ((word16)x[i]) + ((word16)p[i]); | ||
89 | x[i] = (byte)c; | ||
90 | c >>= 8; | ||
91 | } | ||
92 | } | ||
93 | #endif | ||
94 | |||
95 | #if 0 //UNUSED | ||
96 | static void raw_try_sub(byte *x, const byte *p) | ||
97 | { | ||
98 | byte minusp[F25519_SIZE]; | ||
99 | word16 c = 0; | ||
100 | int i; | ||
101 | |||
102 | for (i = 0; i < F25519_SIZE; i++) { | ||
103 | c = ((word16)x[i]) - ((word16)p[i]) - c; | ||
104 | minusp[i] = (byte)c; | ||
105 | c = (c >> 8) & 1; | ||
106 | } | ||
107 | |||
108 | fprime_select(x, minusp, x, (byte)c); | ||
109 | } | ||
110 | #endif | ||
111 | |||
112 | #if 0 //UNUSED | ||
113 | static int prime_msb(const byte *p) | ||
114 | { | ||
115 | int i; | ||
116 | byte x; | ||
117 | int shift = 1; | ||
118 | int z = F25519_SIZE - 1; | ||
119 | |||
120 | /* | ||
121 | Test for any hot bits. | ||
122 | As soon as one instance is encountered set shift to 0. | ||
123 | */ | ||
124 | for (i = F25519_SIZE - 1; i >= 0; i--) { | ||
125 | shift &= ((shift ^ ((-p[i] | p[i]) >> 7)) & 1); | ||
126 | z -= shift; | ||
127 | } | ||
128 | x = p[z]; | ||
129 | z <<= 3; | ||
130 | shift = 1; | ||
131 | for (i = 0; i < 8; i++) { | ||
132 | shift &= ((-(x >> i) | (x >> i)) >> (7 - i) & 1); | ||
133 | z += shift; | ||
134 | } | ||
135 | |||
136 | return z - 1; | ||
137 | } | ||
138 | #endif | ||
139 | |||
140 | #if 0 //UNUSED | ||
141 | static void fprime_add(byte *r, const byte *a, const byte *modulus) | ||
142 | { | ||
143 | raw_add(r, a); | ||
144 | raw_try_sub(r, modulus); | ||
145 | } | ||
146 | #endif | ||
147 | |||
148 | #if 0 //UNUSED | ||
149 | static void fprime_sub(byte *r, const byte *a, const byte *modulus) | ||
150 | { | ||
151 | raw_add(r, modulus); | ||
152 | raw_try_sub(r, a); | ||
153 | raw_try_sub(r, modulus); | ||
154 | } | ||
155 | #endif | ||
156 | |||
157 | #if 0 //UNUSED | ||
158 | static void fprime_mul(byte *r, const byte *a, const byte *b, | ||
159 | const byte *modulus) | ||
160 | { | ||
161 | word16 c = 0; | ||
162 | int i,j; | ||
163 | |||
164 | XMEMSET(r, 0, F25519_SIZE); | ||
165 | |||
166 | for (i = prime_msb(modulus); i >= 0; i--) { | ||
167 | const byte bit = (b[i >> 3] >> (i & 7)) & 1; | ||
168 | byte plusa[F25519_SIZE]; | ||
169 | |||
170 | for (j = 0; j < F25519_SIZE; j++) { | ||
171 | c |= ((word16)r[j]) << 1; | ||
172 | r[j] = (byte)c; | ||
173 | c >>= 8; | ||
174 | } | ||
175 | raw_try_sub(r, modulus); | ||
176 | |||
177 | fprime_copy(plusa, r); | ||
178 | fprime_add(plusa, a, modulus); | ||
179 | |||
180 | fprime_select(r, r, plusa, bit); | ||
181 | } | ||
182 | } | ||
183 | #endif | ||
184 | |||
185 | #if 0 //UNUSED | ||
186 | static void fe_load(byte *x, word32 c) | ||
187 | { | ||
188 | word32 i; | ||
189 | |||
190 | for (i = 0; i < sizeof(c); i++) { | ||
191 | x[i] = c; | ||
192 | c >>= 8; | ||
193 | } | ||
194 | |||
195 | for (; i < F25519_SIZE; i++) | ||
196 | x[i] = 0; | ||
197 | } | ||
198 | #endif | ||
199 | |||
200 | static void fe_normalize(byte *x) | ||
201 | { | ||
202 | byte minusp[F25519_SIZE]; | ||
203 | word16 c; | ||
204 | int i; | ||
205 | |||
206 | /* Reduce using 2^255 = 19 mod p */ | ||
207 | c = (x[31] >> 7) * 19; | ||
208 | x[31] &= 127; | ||
209 | |||
210 | for (i = 0; i < F25519_SIZE; i++) { | ||
211 | c += x[i]; | ||
212 | x[i] = (byte)c; | ||
213 | c >>= 8; | ||
214 | } | ||
215 | |||
216 | /* The number is now less than 2^255 + 18, and therefore less than | ||
217 | * 2p. Try subtracting p, and conditionally load the subtracted | ||
218 | * value if underflow did not occur. | ||
219 | */ | ||
220 | c = 19; | ||
221 | |||
222 | for (i = 0; i + 1 < F25519_SIZE; i++) { | ||
223 | c += x[i]; | ||
224 | minusp[i] = (byte)c; | ||
225 | c >>= 8; | ||
226 | } | ||
227 | |||
228 | c += ((word16)x[i]) - 128; | ||
229 | minusp[31] = (byte)c; | ||
230 | |||
231 | /* Load x-p if no underflow */ | ||
232 | fe_select(x, minusp, x, (c >> 15) & 1); | ||
233 | } | ||
234 | |||
235 | static void lm_add(byte* r, const byte* a, const byte* b) | ||
236 | { | ||
237 | word16 c = 0; | ||
238 | int i; | ||
239 | |||
240 | /* Add */ | ||
241 | for (i = 0; i < F25519_SIZE; i++) { | ||
242 | c >>= 8; | ||
243 | c += ((word16)a[i]) + ((word16)b[i]); | ||
244 | r[i] = (byte)c; | ||
245 | } | ||
246 | |||
247 | /* Reduce with 2^255 = 19 mod p */ | ||
248 | r[31] &= 127; | ||
249 | c = (c >> 7) * 19; | ||
250 | |||
251 | for (i = 0; i < F25519_SIZE; i++) { | ||
252 | c += r[i]; | ||
253 | r[i] = (byte)c; | ||
254 | c >>= 8; | ||
255 | } | ||
256 | } | ||
257 | |||
258 | static void lm_sub(byte* r, const byte* a, const byte* b) | ||
259 | { | ||
260 | word32 c = 0; | ||
261 | int i; | ||
262 | |||
263 | /* Calculate a + 2p - b, to avoid underflow */ | ||
264 | c = 218; | ||
265 | for (i = 0; i + 1 < F25519_SIZE; i++) { | ||
266 | c += 65280 + ((word32)a[i]) - ((word32)b[i]); | ||
267 | r[i] = c; | ||
268 | c >>= 8; | ||
269 | } | ||
270 | |||
271 | c += ((word32)a[31]) - ((word32)b[31]); | ||
272 | r[31] = c & 127; | ||
273 | c = (c >> 7) * 19; | ||
274 | |||
275 | for (i = 0; i < F25519_SIZE; i++) { | ||
276 | c += r[i]; | ||
277 | r[i] = c; | ||
278 | c >>= 8; | ||
279 | } | ||
280 | } | ||
281 | |||
282 | #if 0 //UNUSED | ||
283 | static void lm_neg(byte* r, const byte* a) | ||
284 | { | ||
285 | word32 c = 0; | ||
286 | int i; | ||
287 | |||
288 | /* Calculate 2p - a, to avoid underflow */ | ||
289 | c = 218; | ||
290 | for (i = 0; i + 1 < F25519_SIZE; i++) { | ||
291 | c += 65280 - ((word32)a[i]); | ||
292 | r[i] = c; | ||
293 | c >>= 8; | ||
294 | } | ||
295 | |||
296 | c -= ((word32)a[31]); | ||
297 | r[31] = c & 127; | ||
298 | c = (c >> 7) * 19; | ||
299 | |||
300 | for (i = 0; i < F25519_SIZE; i++) { | ||
301 | c += r[i]; | ||
302 | r[i] = c; | ||
303 | c >>= 8; | ||
304 | } | ||
305 | } | ||
306 | #endif | ||
307 | |||
308 | static void fe_mul__distinct(byte *r, const byte *a, const byte *b) | ||
309 | { | ||
310 | word32 c = 0; | ||
311 | int i; | ||
312 | |||
313 | for (i = 0; i < F25519_SIZE; i++) { | ||
314 | int j; | ||
315 | |||
316 | c >>= 8; | ||
317 | for (j = 0; j <= i; j++) | ||
318 | c += ((word32)a[j]) * ((word32)b[i - j]); | ||
319 | |||
320 | for (; j < F25519_SIZE; j++) | ||
321 | c += ((word32)a[j]) * | ||
322 | ((word32)b[i + F25519_SIZE - j]) * 38; | ||
323 | |||
324 | r[i] = c; | ||
325 | } | ||
326 | |||
327 | r[31] &= 127; | ||
328 | c = (c >> 7) * 19; | ||
329 | |||
330 | for (i = 0; i < F25519_SIZE; i++) { | ||
331 | c += r[i]; | ||
332 | r[i] = c; | ||
333 | c >>= 8; | ||
334 | } | ||
335 | } | ||
336 | |||
337 | #if 0 //UNUSED | ||
338 | static void lm_mul(byte *r, const byte* a, const byte *b) | ||
339 | { | ||
340 | byte tmp[F25519_SIZE]; | ||
341 | |||
342 | fe_mul__distinct(tmp, a, b); | ||
343 | lm_copy(r, tmp); | ||
344 | } | ||
345 | #endif | ||
346 | |||
347 | static void fe_mul_c(byte *r, const byte *a, word32 b) | ||
348 | { | ||
349 | word32 c = 0; | ||
350 | int i; | ||
351 | |||
352 | for (i = 0; i < F25519_SIZE; i++) { | ||
353 | c >>= 8; | ||
354 | c += b * ((word32)a[i]); | ||
355 | r[i] = c; | ||
356 | } | ||
357 | |||
358 | r[31] &= 127; | ||
359 | c >>= 7; | ||
360 | c *= 19; | ||
361 | |||
362 | for (i = 0; i < F25519_SIZE; i++) { | ||
363 | c += r[i]; | ||
364 | r[i] = c; | ||
365 | c >>= 8; | ||
366 | } | ||
367 | } | ||
368 | |||
369 | static void fe_inv__distinct(byte *r, const byte *x) | ||
370 | { | ||
371 | byte s[F25519_SIZE]; | ||
372 | int i; | ||
373 | |||
374 | /* This is a prime field, so by Fermat's little theorem: | ||
375 | * | ||
376 | * x^(p-1) = 1 mod p | ||
377 | * | ||
378 | * Therefore, raise to (p-2) = 2^255-21 to get a multiplicative | ||
379 | * inverse. | ||
380 | * | ||
381 | * This is a 255-bit binary number with the digits: | ||
382 | * | ||
383 | * 11111111... 01011 | ||
384 | * | ||
385 | * We compute the result by the usual binary chain, but | ||
386 | * alternate between keeping the accumulator in r and s, so as | ||
387 | * to avoid copying temporaries. | ||
388 | */ | ||
389 | |||
390 | /* 1 1 */ | ||
391 | fe_mul__distinct(s, x, x); | ||
392 | fe_mul__distinct(r, s, x); | ||
393 | |||
394 | /* 1 x 248 */ | ||
395 | for (i = 0; i < 248; i++) { | ||
396 | fe_mul__distinct(s, r, r); | ||
397 | fe_mul__distinct(r, s, x); | ||
398 | } | ||
399 | |||
400 | /* 0 */ | ||
401 | fe_mul__distinct(s, r, r); | ||
402 | |||
403 | /* 1 */ | ||
404 | fe_mul__distinct(r, s, s); | ||
405 | fe_mul__distinct(s, r, x); | ||
406 | |||
407 | /* 0 */ | ||
408 | fe_mul__distinct(r, s, s); | ||
409 | |||
410 | /* 1 */ | ||
411 | fe_mul__distinct(s, r, r); | ||
412 | fe_mul__distinct(r, s, x); | ||
413 | |||
414 | /* 1 */ | ||
415 | fe_mul__distinct(s, r, r); | ||
416 | fe_mul__distinct(r, s, x); | ||
417 | } | ||
418 | |||
419 | #if 0 //UNUSED | ||
420 | static void lm_invert(byte *r, const byte *x) | ||
421 | { | ||
422 | byte tmp[F25519_SIZE]; | ||
423 | |||
424 | fe_inv__distinct(tmp, x); | ||
425 | lm_copy(r, tmp); | ||
426 | } | ||
427 | #endif | ||
428 | |||
429 | #if 0 //UNUSED | ||
430 | /* Raise x to the power of (p-5)/8 = 2^252-3, using s for temporary | ||
431 | * storage. | ||
432 | */ | ||
433 | static void exp2523(byte *r, const byte *x, byte *s) | ||
434 | { | ||
435 | int i; | ||
436 | |||
437 | /* This number is a 252-bit number with the binary expansion: | ||
438 | * | ||
439 | * 111111... 01 | ||
440 | */ | ||
441 | |||
442 | /* 1 1 */ | ||
443 | fe_mul__distinct(r, x, x); | ||
444 | fe_mul__distinct(s, r, x); | ||
445 | |||
446 | /* 1 x 248 */ | ||
447 | for (i = 0; i < 248; i++) { | ||
448 | fe_mul__distinct(r, s, s); | ||
449 | fe_mul__distinct(s, r, x); | ||
450 | } | ||
451 | |||
452 | /* 0 */ | ||
453 | fe_mul__distinct(r, s, s); | ||
454 | |||
455 | /* 1 */ | ||
456 | fe_mul__distinct(s, r, r); | ||
457 | fe_mul__distinct(r, s, x); | ||
458 | } | ||
459 | #endif | ||
460 | |||
461 | #if 0 //UNUSED | ||
462 | static void fe_sqrt(byte *r, const byte *a) | ||
463 | { | ||
464 | byte v[F25519_SIZE]; | ||
465 | byte i[F25519_SIZE]; | ||
466 | byte x[F25519_SIZE]; | ||
467 | byte y[F25519_SIZE]; | ||
468 | |||
469 | /* v = (2a)^((p-5)/8) [x = 2a] */ | ||
470 | fe_mul_c(x, a, 2); | ||
471 | exp2523(v, x, y); | ||
472 | |||
473 | /* i = 2av^2 - 1 */ | ||
474 | fe_mul__distinct(y, v, v); | ||
475 | fe_mul__distinct(i, x, y); | ||
476 | fe_load(y, 1); | ||
477 | lm_sub(i, i, y); | ||
478 | |||
479 | /* r = avi */ | ||
480 | fe_mul__distinct(x, v, a); | ||
481 | fe_mul__distinct(r, x, i); | ||
482 | } | ||
483 | #endif | ||
484 | |||
485 | /* Differential addition */ | ||
486 | static void xc_diffadd(byte *x5, byte *z5, | ||
487 | const byte *x1, const byte *z1, | ||
488 | const byte *x2, const byte *z2, | ||
489 | const byte *x3, const byte *z3) | ||
490 | { | ||
491 | /* Explicit formulas database: dbl-1987-m3 | ||
492 | * | ||
493 | * source 1987 Montgomery "Speeding the Pollard and elliptic curve | ||
494 | * methods of factorization", page 261, fifth display, plus | ||
495 | * common-subexpression elimination | ||
496 | * compute A = X2+Z2 | ||
497 | * compute B = X2-Z2 | ||
498 | * compute C = X3+Z3 | ||
499 | * compute D = X3-Z3 | ||
500 | * compute DA = D A | ||
501 | * compute CB = C B | ||
502 | * compute X5 = Z1(DA+CB)^2 | ||
503 | * compute Z5 = X1(DA-CB)^2 | ||
504 | */ | ||
505 | byte da[F25519_SIZE]; | ||
506 | byte cb[F25519_SIZE]; | ||
507 | byte a[F25519_SIZE]; | ||
508 | byte b[F25519_SIZE]; | ||
509 | |||
510 | lm_add(a, x2, z2); | ||
511 | lm_sub(b, x3, z3); /* D */ | ||
512 | fe_mul__distinct(da, a, b); | ||
513 | |||
514 | lm_sub(b, x2, z2); | ||
515 | lm_add(a, x3, z3); /* C */ | ||
516 | fe_mul__distinct(cb, a, b); | ||
517 | |||
518 | lm_add(a, da, cb); | ||
519 | fe_mul__distinct(b, a, a); | ||
520 | fe_mul__distinct(x5, z1, b); | ||
521 | |||
522 | lm_sub(a, da, cb); | ||
523 | fe_mul__distinct(b, a, a); | ||
524 | fe_mul__distinct(z5, x1, b); | ||
525 | } | ||
526 | |||
527 | /* Double an X-coordinate */ | ||
528 | static void xc_double(byte *x3, byte *z3, | ||
529 | const byte *x1, const byte *z1) | ||
530 | { | ||
531 | /* Explicit formulas database: dbl-1987-m | ||
532 | * | ||
533 | * source 1987 Montgomery "Speeding the Pollard and elliptic | ||
534 | * curve methods of factorization", page 261, fourth display | ||
535 | * compute X3 = (X1^2-Z1^2)^2 | ||
536 | * compute Z3 = 4 X1 Z1 (X1^2 + a X1 Z1 + Z1^2) | ||
537 | */ | ||
538 | byte x1sq[F25519_SIZE]; | ||
539 | byte z1sq[F25519_SIZE]; | ||
540 | byte x1z1[F25519_SIZE]; | ||
541 | byte a[F25519_SIZE]; | ||
542 | |||
543 | fe_mul__distinct(x1sq, x1, x1); | ||
544 | fe_mul__distinct(z1sq, z1, z1); | ||
545 | fe_mul__distinct(x1z1, x1, z1); | ||
546 | |||
547 | lm_sub(a, x1sq, z1sq); | ||
548 | fe_mul__distinct(x3, a, a); | ||
549 | |||
550 | fe_mul_c(a, x1z1, 486662); | ||
551 | lm_add(a, x1sq, a); | ||
552 | lm_add(a, z1sq, a); | ||
553 | fe_mul__distinct(x1sq, x1z1, a); | ||
554 | fe_mul_c(z3, x1sq, 4); | ||
555 | } | ||
556 | |||
557 | void FAST_FUNC curve25519(byte *result, const byte *e, const byte *q) | ||
558 | { | ||
559 | int i; | ||
560 | |||
561 | struct { | ||
562 | /* from wolfssl-3.15.3/wolfssl/wolfcrypt/fe_operations.h */ | ||
563 | /*static const*/ byte f25519_one[F25519_SIZE]; // = {1}; | ||
564 | |||
565 | /* Current point: P_m */ | ||
566 | byte xm[F25519_SIZE]; | ||
567 | byte zm[F25519_SIZE]; // = {1}; | ||
568 | /* Predecessor: P_(m-1) */ | ||
569 | byte xm1[F25519_SIZE]; // = {1}; | ||
570 | byte zm1[F25519_SIZE]; // = {0}; | ||
571 | } z; | ||
572 | #define f25519_one z.f25519_one | ||
573 | #define xm z.xm | ||
574 | #define zm z.zm | ||
575 | #define xm1 z.xm1 | ||
576 | #define zm1 z.zm1 | ||
577 | memset(&z, 0, sizeof(z)); | ||
578 | f25519_one[0] = 1; | ||
579 | zm[0] = 1; | ||
580 | xm1[0] = 1; | ||
581 | |||
582 | /* Note: bit 254 is assumed to be 1 */ | ||
583 | lm_copy(xm, q); | ||
584 | |||
585 | for (i = 253; i >= 0; i--) { | ||
586 | const int bit = (e[i >> 3] >> (i & 7)) & 1; | ||
587 | byte xms[F25519_SIZE]; | ||
588 | byte zms[F25519_SIZE]; | ||
589 | |||
590 | /* From P_m and P_(m-1), compute P_(2m) and P_(2m-1) */ | ||
591 | xc_diffadd(xm1, zm1, q, f25519_one, xm, zm, xm1, zm1); | ||
592 | xc_double(xm, zm, xm, zm); | ||
593 | |||
594 | /* Compute P_(2m+1) */ | ||
595 | xc_diffadd(xms, zms, xm1, zm1, xm, zm, q, f25519_one); | ||
596 | |||
597 | /* Select: | ||
598 | * bit = 1 --> (P_(2m+1), P_(2m)) | ||
599 | * bit = 0 --> (P_(2m), P_(2m-1)) | ||
600 | */ | ||
601 | fe_select(xm1, xm1, xm, bit); | ||
602 | fe_select(zm1, zm1, zm, bit); | ||
603 | fe_select(xm, xm, xms, bit); | ||
604 | fe_select(zm, zm, zms, bit); | ||
605 | } | ||
606 | |||
607 | /* Freeze out of projective coordinates */ | ||
608 | fe_inv__distinct(zm1, zm); | ||
609 | fe_mul__distinct(result, zm1, xm); | ||
610 | fe_normalize(result); | ||
611 | } | ||
diff --git a/networking/tls_fe.h b/networking/tls_fe.h new file mode 100644 index 000000000..fe8cff228 --- /dev/null +++ b/networking/tls_fe.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2018 Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | #define CURVE25519_KEYSIZE 32 | ||
7 | void curve25519(uint8_t *result, const uint8_t *e, const uint8_t *q) FAST_FUNC; | ||
diff --git a/networking/tls_rsa.c b/networking/tls_rsa.c index 60c54248e..631397e4d 100644 --- a/networking/tls_rsa.c +++ b/networking/tls_rsa.c | |||
@@ -179,7 +179,7 @@ done: | |||
179 | return res; | 179 | return res; |
180 | } | 180 | } |
181 | 181 | ||
182 | int32 psRsaEncryptPub(psPool_t *pool, psRsaKey_t *key, | 182 | int32 FAST_FUNC psRsaEncryptPub(psPool_t *pool, psRsaKey_t *key, |
183 | unsigned char *in, uint32 inlen, | 183 | unsigned char *in, uint32 inlen, |
184 | unsigned char *out, uint32 outlen, void *data) | 184 | unsigned char *out, uint32 outlen, void *data) |
185 | { | 185 | { |
diff --git a/networking/tls_rsa.h b/networking/tls_rsa.h index c464ed552..82bea2a67 100644 --- a/networking/tls_rsa.h +++ b/networking/tls_rsa.h | |||
@@ -13,8 +13,20 @@ typedef struct { | |||
13 | //bbox psPool_t *pool; | 13 | //bbox psPool_t *pool; |
14 | } psRsaKey_t; | 14 | } psRsaKey_t; |
15 | 15 | ||
16 | static ALWAYS_INLINE void psRsaKey_clear(psRsaKey_t *key) | ||
17 | { | ||
18 | pstm_clear(&key->N); | ||
19 | pstm_clear(&key->e); | ||
20 | pstm_clear(&key->d); | ||
21 | pstm_clear(&key->p); | ||
22 | pstm_clear(&key->q); | ||
23 | pstm_clear(&key->dP); | ||
24 | pstm_clear(&key->dQ); | ||
25 | pstm_clear(&key->qP); | ||
26 | } | ||
27 | |||
16 | #define psRsaEncryptPub(pool, key, in, inlen, out, outlen, data) \ | 28 | #define psRsaEncryptPub(pool, key, in, inlen, out, outlen, data) \ |
17 | psRsaEncryptPub( key, in, inlen, out, outlen) | 29 | psRsaEncryptPub( key, in, inlen, out, outlen) |
18 | int32 psRsaEncryptPub(psPool_t *pool, psRsaKey_t *key, | 30 | int32 psRsaEncryptPub(psPool_t *pool, psRsaKey_t *key, |
19 | unsigned char *in, uint32 inlen, | 31 | unsigned char *in, uint32 inlen, |
20 | unsigned char *out, uint32 outlen, void *data); | 32 | unsigned char *out, uint32 outlen, void *data) FAST_FUNC; |
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 66e4b6c6a..3c6129249 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c | |||
@@ -814,7 +814,9 @@ static NOINLINE int send_d6_renew(uint32_t xid, struct in6_addr *server_ipv6, st | |||
814 | } | 814 | } |
815 | 815 | ||
816 | /* Unicast a DHCP release message */ | 816 | /* Unicast a DHCP release message */ |
817 | static int send_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6) | 817 | static |
818 | ALWAYS_INLINE /* one caller, help compiler to use this fact */ | ||
819 | int send_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6) | ||
818 | { | 820 | { |
819 | struct d6_packet packet; | 821 | struct d6_packet packet; |
820 | uint8_t *opt_ptr; | 822 | uint8_t *opt_ptr; |
@@ -1738,8 +1740,9 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1738 | /* note: "int timeout" will not overflow even with 0xffffffff inputs here: */ | 1740 | /* note: "int timeout" will not overflow even with 0xffffffff inputs here: */ |
1739 | timeout = (prefix_timeout < address_timeout ? prefix_timeout : address_timeout) / 2; | 1741 | timeout = (prefix_timeout < address_timeout ? prefix_timeout : address_timeout) / 2; |
1740 | /* paranoia: must not be too small */ | 1742 | /* paranoia: must not be too small */ |
1741 | if (timeout < 0x10) | 1743 | /* timeout > 60 - ensures at least one unicast renew attempt */ |
1742 | timeout = 0x10; | 1744 | if (timeout < 61) |
1745 | timeout = 61; | ||
1743 | /* enter bound state */ | 1746 | /* enter bound state */ |
1744 | d6_run_script(packet.d6_options, packet_end, | 1747 | d6_run_script(packet.d6_options, packet_end, |
1745 | (state == REQUESTING ? "bound" : "renew")); | 1748 | (state == REQUESTING ? "bound" : "renew")); |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index ab3e5a463..4b23e4d39 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -850,7 +850,9 @@ static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t req | |||
850 | #endif | 850 | #endif |
851 | 851 | ||
852 | /* Unicast a DHCP release message */ | 852 | /* Unicast a DHCP release message */ |
853 | static int send_release(uint32_t server, uint32_t ciaddr) | 853 | static |
854 | ALWAYS_INLINE /* one caller, help compiler to use this fact */ | ||
855 | int send_release(uint32_t server, uint32_t ciaddr) | ||
854 | { | 856 | { |
855 | struct dhcp_packet packet; | 857 | struct dhcp_packet packet; |
856 | 858 | ||
@@ -1725,8 +1727,9 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1725 | move_from_unaligned32(lease_seconds, temp); | 1727 | move_from_unaligned32(lease_seconds, temp); |
1726 | lease_seconds = ntohl(lease_seconds); | 1728 | lease_seconds = ntohl(lease_seconds); |
1727 | /* paranoia: must not be too small and not prone to overflows */ | 1729 | /* paranoia: must not be too small and not prone to overflows */ |
1728 | if (lease_seconds < 0x10) | 1730 | /* timeout > 60 - ensures at least one unicast renew attempt */ |
1729 | lease_seconds = 0x10; | 1731 | if (lease_seconds < 2 * 61) |
1732 | lease_seconds = 2 * 61; | ||
1730 | //if (lease_seconds > 0x7fffffff) | 1733 | //if (lease_seconds > 0x7fffffff) |
1731 | // lease_seconds = 0x7fffffff; | 1734 | // lease_seconds = 0x7fffffff; |
1732 | //^^^not necessary since "timeout = lease_seconds / 2" | 1735 | //^^^not necessary since "timeout = lease_seconds / 2" |
diff --git a/networking/wget.c b/networking/wget.c index bd2f4edcf..ae5c945d0 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -233,20 +233,19 @@ struct globals { | |||
233 | char *fname_out; /* where to direct output (-O) */ | 233 | char *fname_out; /* where to direct output (-O) */ |
234 | const char *proxy_flag; /* Use proxies if env vars are set */ | 234 | const char *proxy_flag; /* Use proxies if env vars are set */ |
235 | const char *user_agent; /* "User-Agent" header field */ | 235 | const char *user_agent; /* "User-Agent" header field */ |
236 | int output_fd; | ||
237 | int o_flags; | ||
236 | #if ENABLE_FEATURE_WGET_TIMEOUT | 238 | #if ENABLE_FEATURE_WGET_TIMEOUT |
237 | unsigned timeout_seconds; | 239 | unsigned timeout_seconds; |
238 | bool die_if_timed_out; | 240 | smallint die_if_timed_out; |
239 | #endif | 241 | #endif |
240 | int output_fd; | ||
241 | int o_flags; | ||
242 | smallint chunked; /* chunked transfer encoding */ | 242 | smallint chunked; /* chunked transfer encoding */ |
243 | smallint got_clen; /* got content-length: from server */ | 243 | smallint got_clen; /* got content-length: from server */ |
244 | /* Local downloads do benefit from big buffer. | 244 | /* Local downloads do benefit from big buffer. |
245 | * With 512 byte buffer, it was measured to be | 245 | * With 512 byte buffer, it was measured to be |
246 | * an order of magnitude slower than with big one. | 246 | * an order of magnitude slower than with big one. |
247 | */ | 247 | */ |
248 | uint64_t just_to_align_next_member; | 248 | char wget_buf[CONFIG_FEATURE_COPYBUF_KB*1024] ALIGNED(sizeof(long)); |
249 | char wget_buf[CONFIG_FEATURE_COPYBUF_KB*1024]; | ||
250 | } FIX_ALIASING; | 249 | } FIX_ALIASING; |
251 | #define G (*ptr_to_globals) | 250 | #define G (*ptr_to_globals) |
252 | #define INIT_G() do { \ | 251 | #define INIT_G() do { \ |
@@ -283,13 +282,15 @@ enum { | |||
283 | #if ENABLE_FEATURE_WGET_STATUSBAR | 282 | #if ENABLE_FEATURE_WGET_STATUSBAR |
284 | static void progress_meter(int flag) | 283 | static void progress_meter(int flag) |
285 | { | 284 | { |
285 | int notty; | ||
286 | |||
286 | if (option_mask32 & WGET_OPT_QUIET) | 287 | if (option_mask32 & WGET_OPT_QUIET) |
287 | return; | 288 | return; |
288 | 289 | ||
289 | if (flag == PROGRESS_START) | 290 | if (flag == PROGRESS_START) |
290 | bb_progress_init(&G.pmt, G.curfile); | 291 | bb_progress_init(&G.pmt, G.curfile); |
291 | 292 | ||
292 | bb_progress_update(&G.pmt, | 293 | notty = bb_progress_update(&G.pmt, |
293 | G.beg_range, | 294 | G.beg_range, |
294 | G.transferred, | 295 | G.transferred, |
295 | (G.chunked || !G.got_clen) ? 0 : G.beg_range + G.transferred + G.content_len | 296 | (G.chunked || !G.got_clen) ? 0 : G.beg_range + G.transferred + G.content_len |
@@ -297,7 +298,8 @@ static void progress_meter(int flag) | |||
297 | 298 | ||
298 | if (flag == PROGRESS_END) { | 299 | if (flag == PROGRESS_END) { |
299 | bb_progress_free(&G.pmt); | 300 | bb_progress_free(&G.pmt); |
300 | bb_putchar_stderr('\n'); | 301 | if (notty == 0) |
302 | bb_putchar_stderr('\n'); /* it's tty */ | ||
301 | G.transferred = 0; | 303 | G.transferred = 0; |
302 | } | 304 | } |
303 | } | 305 | } |
@@ -346,9 +348,8 @@ static void strip_ipv6_scope_id(char *host) | |||
346 | /* Base64-encode character string. */ | 348 | /* Base64-encode character string. */ |
347 | static char *base64enc(const char *str) | 349 | static char *base64enc(const char *str) |
348 | { | 350 | { |
349 | unsigned len = strlen(str); | 351 | /* paranoia */ |
350 | if (len > sizeof(G.wget_buf)/4*3 - 10) /* paranoia */ | 352 | unsigned len = strnlen(str, sizeof(G.wget_buf)/4*3 - 10); |
351 | len = sizeof(G.wget_buf)/4*3 - 10; | ||
352 | bb_uuencode(G.wget_buf, str, len, bb_uuenc_tbl_base64); | 353 | bb_uuencode(G.wget_buf, str, len, bb_uuenc_tbl_base64); |
353 | return G.wget_buf; | 354 | return G.wget_buf; |
354 | } | 355 | } |
@@ -723,8 +724,10 @@ static void spawn_ssl_client(const char *host, int network_fd, int flags) | |||
723 | int pid; | 724 | int pid; |
724 | char *servername, *p; | 725 | char *servername, *p; |
725 | 726 | ||
726 | if (!(option_mask32 & WGET_OPT_NO_CHECK_CERT)) | 727 | if (!(option_mask32 & WGET_OPT_NO_CHECK_CERT)) { |
728 | option_mask32 |= WGET_OPT_NO_CHECK_CERT; | ||
727 | bb_error_msg("note: TLS certificate validation not implemented"); | 729 | bb_error_msg("note: TLS certificate validation not implemented"); |
730 | } | ||
728 | 731 | ||
729 | servername = xstrdup(host); | 732 | servername = xstrdup(host); |
730 | p = strrchr(servername, ':'); | 733 | p = strrchr(servername, ':'); |