aboutsummaryrefslogtreecommitdiff
path: root/networking
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-10-13 14:37:51 +0100
committerRon Yorston <rmy@pobox.com>2021-10-13 14:37:51 +0100
commit0ecf1aea459571b48dc68ddc2b7b9265740fa960 (patch)
tree491d6184a44b8b525a4ca35759d622aecd7f6344 /networking
parent4859ddcb20616718efbea12c6bf8b27c469b68de (diff)
parentaaf3d5ba74c5da97ff80b61f30cb8dd225d39096 (diff)
downloadbusybox-w32-0ecf1aea459571b48dc68ddc2b7b9265740fa960.tar.gz
busybox-w32-0ecf1aea459571b48dc68ddc2b7b9265740fa960.tar.bz2
busybox-w32-0ecf1aea459571b48dc68ddc2b7b9265740fa960.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'networking')
-rw-r--r--networking/Config.src26
-rw-r--r--networking/brctl.c2
-rw-r--r--networking/httpd.c9
-rw-r--r--networking/ifplugd.c2
-rw-r--r--networking/ip.c2
-rw-r--r--networking/libiproute/iplink.c35
-rw-r--r--networking/nslookup.c2
-rw-r--r--networking/ntpd.c4
-rw-r--r--networking/tls.c149
-rw-r--r--networking/tls.h5
-rw-r--r--networking/tls_fe.c54
-rw-r--r--networking/tls_pstm.h1
-rw-r--r--networking/tls_sp_c32.c1471
-rw-r--r--networking/tls_symmetric.h511
-rw-r--r--networking/wget.c26
15 files changed, 1206 insertions, 1093 deletions
diff --git a/networking/Config.src b/networking/Config.src
index 04d644bc9..0942645c3 100644
--- a/networking/Config.src
+++ b/networking/Config.src
@@ -46,6 +46,32 @@ config VERBOSE_RESOLUTION_ERRORS
46 "can't resolve 'hostname.com'" and want to know more. 46 "can't resolve 'hostname.com'" and want to know more.
47 This may increase size of your executable a bit. 47 This may increase size of your executable a bit.
48 48
49config FEATURE_ETC_NETWORKS
50 bool "Support /etc/networks"
51 default n
52 help
53 Enable support for network names in /etc/networks. This is
54 a rarely used feature which allows you to use names
55 instead of IP/mask pairs in route command.
56
57config FEATURE_ETC_SERVICES
58 bool "Consult /etc/services even for well-known ports"
59 default n
60 help
61 Look up e.g. "telnet" and "http" in /etc/services file
62 instead of assuming ports 23 and 80.
63 This is almost never necessary (everybody uses standard ports),
64 and it makes sense to avoid reading this file.
65 If you disable this option, in the cases where port is explicitly
66 specified as a service name (e.g. "telnet HOST PORTNAME"),
67 it will still be looked up in /etc/services.
68
69config FEATURE_HWIB
70 bool "Support infiniband HW"
71 default y
72 help
73 Support for printing infiniband addresses in network applets.
74
49config FEATURE_TLS_SHA1 75config FEATURE_TLS_SHA1
50 bool "In TLS code, support ciphers which use deprecated SHA1" 76 bool "In TLS code, support ciphers which use deprecated SHA1"
51 depends on TLS 77 depends on TLS
diff --git a/networking/brctl.c b/networking/brctl.c
index c83aac6e0..956bd91f3 100644
--- a/networking/brctl.c
+++ b/networking/brctl.c
@@ -318,7 +318,7 @@ static void printf_xstrtou(const char *fmt)
318 printf(fmt, xstrtou(filedata, 0)); 318 printf(fmt, xstrtou(filedata, 0));
319} 319}
320 320
321static void show_bridge_port(const char *name) 321static NOINLINE void show_bridge_port(const char *name)
322{ 322{
323 char pathbuf[IFNAMSIZ + sizeof("/brport/forward_delay_timer") + 8]; 323 char pathbuf[IFNAMSIZ + sizeof("/brport/forward_delay_timer") + 8];
324 char *sfx; 324 char *sfx;
diff --git a/networking/httpd.c b/networking/httpd.c
index 71e3a723f..6cc189272 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -281,7 +281,7 @@
281//usage: IF_NOT_PLATFORM_MINGW32( 281//usage: IF_NOT_PLATFORM_MINGW32(
282//usage: "\n -i Inetd mode" 282//usage: "\n -i Inetd mode"
283//usage: ) 283//usage: )
284//usage: "\n -f Don't daemonize" 284//usage: "\n -f Run in foreground"
285//usage: "\n -v[v] Verbose" 285//usage: "\n -v[v] Verbose"
286//usage: "\n -p [IP:]PORT Bind to IP:PORT (default *:"STR(CONFIG_FEATURE_HTTPD_PORT_DEFAULT)")" 286//usage: "\n -p [IP:]PORT Bind to IP:PORT (default *:"STR(CONFIG_FEATURE_HTTPD_PORT_DEFAULT)")"
287//usage: IF_FEATURE_HTTPD_SETUID( 287//usage: IF_FEATURE_HTTPD_SETUID(
@@ -1918,14 +1918,17 @@ static NOINLINE void send_file_and_exit(const char *url, int what)
1918 send_headers(HTTP_OK); 1918 send_headers(HTTP_OK);
1919#if ENABLE_FEATURE_USE_SENDFILE 1919#if ENABLE_FEATURE_USE_SENDFILE
1920 { 1920 {
1921 off_t offset = (range_start < 0) ? 0 : range_start; 1921 off_t offset;
1922 if (range_start < 0)
1923 range_start = 0;
1924 offset = range_start;
1922 while (1) { 1925 while (1) {
1923 /* sz is rounded down to 64k */ 1926 /* sz is rounded down to 64k */
1924 ssize_t sz = MAXINT(ssize_t) - 0xffff; 1927 ssize_t sz = MAXINT(ssize_t) - 0xffff;
1925 IF_FEATURE_HTTPD_RANGES(if (sz > range_len) sz = range_len;) 1928 IF_FEATURE_HTTPD_RANGES(if (sz > range_len) sz = range_len;)
1926 count = sendfile(STDOUT_FILENO, fd, &offset, sz); 1929 count = sendfile(STDOUT_FILENO, fd, &offset, sz);
1927 if (count < 0) { 1930 if (count < 0) {
1928 if (offset == range_start) 1931 if (offset == range_start) /* was it the very 1st sendfile? */
1929 break; /* fall back to read/write loop */ 1932 break; /* fall back to read/write loop */
1930 goto fin; 1933 goto fin;
1931 } 1934 }
diff --git a/networking/ifplugd.c b/networking/ifplugd.c
index 18dcaff96..c4b6b9584 100644
--- a/networking/ifplugd.c
+++ b/networking/ifplugd.c
@@ -20,7 +20,7 @@
20//usage: "[OPTIONS]" 20//usage: "[OPTIONS]"
21//usage:#define ifplugd_full_usage "\n\n" 21//usage:#define ifplugd_full_usage "\n\n"
22//usage: "Network interface plug detection daemon\n" 22//usage: "Network interface plug detection daemon\n"
23//usage: "\n -n Don't daemonize" 23//usage: "\n -n Run in foreground"
24//usage: "\n -s Don't log to syslog" 24//usage: "\n -s Don't log to syslog"
25//usage: "\n -i IFACE Interface" 25//usage: "\n -i IFACE Interface"
26//usage: "\n -f/-F Treat link detection error as link down/link up" 26//usage: "\n -f/-F Treat link detection error as link down/link up"
diff --git a/networking/ip.c b/networking/ip.c
index 85b1ba080..7c3208699 100644
--- a/networking/ip.c
+++ b/networking/ip.c
@@ -152,7 +152,7 @@
152//usage:#define iplink_trivial_usage 152//usage:#define iplink_trivial_usage
153//usage: /*Usage:iplink*/"set IFACE [up|down] [arp on|off] [multicast on|off]\n" 153//usage: /*Usage:iplink*/"set IFACE [up|down] [arp on|off] [multicast on|off]\n"
154//usage: " [promisc on|off] [mtu NUM] [name NAME] [qlen NUM] [address MAC]\n" 154//usage: " [promisc on|off] [mtu NUM] [name NAME] [qlen NUM] [address MAC]\n"
155//usage: " [master IFACE | nomaster]" 155//usage: " [master IFACE | nomaster] [netns PID]"
156// * short help shows only "set" command, long help continues (with just one "\n") 156// * short help shows only "set" command, long help continues (with just one "\n")
157// * and shows all other commands: 157// * and shows all other commands:
158//usage:#define iplink_full_usage "\n" 158//usage:#define iplink_full_usage "\n"
diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c
index 1a1064bdc..68d199044 100644
--- a/networking/libiproute/iplink.c
+++ b/networking/libiproute/iplink.c
@@ -153,6 +153,30 @@ static void set_master(char *dev, int master)
153} 153}
154 154
155/* Exits on error */ 155/* Exits on error */
156static void set_netns(char *dev, int netns)
157{
158 struct rtnl_handle rth;
159 struct {
160 struct nlmsghdr n;
161 struct ifinfomsg i;
162 char buf[1024];
163 } req;
164
165 memset(&req, 0, sizeof(req));
166 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
167 req.n.nlmsg_flags = NLM_F_REQUEST;
168 req.n.nlmsg_type = RTM_NEWLINK;
169 req.i.ifi_family = preferred_family;
170
171 xrtnl_open(&rth);
172 req.i.ifi_index = xll_name_to_index(dev);
173 //printf("netns %i for %i\n", netns, req.i.ifi_index);
174 addattr_l(&req.n, sizeof(req), IFLA_NET_NS_PID, &netns, 4);
175 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
176 xfunc_die();
177}
178
179/* Exits on error */
156static int get_address(char *dev, int *htype) 180static int get_address(char *dev, int *htype)
157{ 181{
158 struct ifreq ifr; 182 struct ifreq ifr;
@@ -226,6 +250,7 @@ static int do_set(char **argv)
226 int qlen = -1; 250 int qlen = -1;
227 int mtu = -1; 251 int mtu = -1;
228 int master = -1; 252 int master = -1;
253 int netns = -1;
229 char *newaddr = NULL; 254 char *newaddr = NULL;
230 char *newbrd = NULL; 255 char *newbrd = NULL;
231 struct ifreq ifr0, ifr1; 256 struct ifreq ifr0, ifr1;
@@ -234,11 +259,11 @@ static int do_set(char **argv)
234 /* If you add stuff here, update iplink_full_usage */ 259 /* If you add stuff here, update iplink_full_usage */
235 static const char keywords[] ALIGN1 = 260 static const char keywords[] ALIGN1 =
236 "up\0""down\0""name\0""mtu\0""qlen\0""multicast\0" 261 "up\0""down\0""name\0""mtu\0""qlen\0""multicast\0"
237 "arp\0""promisc\0""address\0" 262 "arp\0""promisc\0""address\0""netns\0"
238 "master\0""nomaster\0" 263 "master\0""nomaster\0"
239 "dev\0" /* must be last */; 264 "dev\0" /* must be last */;
240 enum { ARG_up = 0, ARG_down, ARG_name, ARG_mtu, ARG_qlen, ARG_multicast, 265 enum { ARG_up = 0, ARG_down, ARG_name, ARG_mtu, ARG_qlen, ARG_multicast,
241 ARG_arp, ARG_promisc, ARG_addr, 266 ARG_arp, ARG_promisc, ARG_addr, ARG_netns,
242 ARG_master, ARG_nomaster, 267 ARG_master, ARG_nomaster,
243 ARG_dev }; 268 ARG_dev };
244 enum { PARM_on = 0, PARM_off }; 269 enum { PARM_on = 0, PARM_off };
@@ -276,6 +301,9 @@ static int do_set(char **argv)
276 master = xll_name_to_index(*argv); 301 master = xll_name_to_index(*argv);
277 } else if (key == ARG_nomaster) { 302 } else if (key == ARG_nomaster) {
278 master = 0; 303 master = 0;
304 } else if (key == ARG_netns) {
305 NEXT_ARG();
306 netns = get_unsigned(*argv, "netns");
279 } else if (key >= ARG_dev) { 307 } else if (key >= ARG_dev) {
280 /* ^^^^^^ ">=" here results in "dev IFACE" treated as default */ 308 /* ^^^^^^ ">=" here results in "dev IFACE" treated as default */
281 if (key == ARG_dev) { 309 if (key == ARG_dev) {
@@ -463,6 +491,9 @@ static int do_set(char **argv)
463 if (master != -1) { 491 if (master != -1) {
464 set_master(dev, master); 492 set_master(dev, master);
465 } 493 }
494 if (netns != -1) {
495 set_netns(dev, netns);
496 }
466 if (mask) 497 if (mask)
467 do_chflags(dev, flags, mask); 498 do_chflags(dev, flags, mask);
468 return 0; 499 return 0;
diff --git a/networking/nslookup.c b/networking/nslookup.c
index de7b5c0e7..6da97baf4 100644
--- a/networking/nslookup.c
+++ b/networking/nslookup.c
@@ -335,7 +335,7 @@ enum {
335 OPT_debug = (1 << 0), 335 OPT_debug = (1 << 0),
336}; 336};
337 337
338static int parse_reply(const unsigned char *msg, size_t len) 338static NOINLINE int parse_reply(const unsigned char *msg, size_t len)
339{ 339{
340 HEADER *header; 340 HEADER *header;
341 341
diff --git a/networking/ntpd.c b/networking/ntpd.c
index 6bf6c4e07..204e1d7c2 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -78,7 +78,7 @@
78//usage:#define ntpd_full_usage "\n\n" 78//usage:#define ntpd_full_usage "\n\n"
79//usage: "NTP client/server\n" 79//usage: "NTP client/server\n"
80//usage: "\n -d[d] Verbose" 80//usage: "\n -d[d] Verbose"
81//usage: "\n -n Do not daemonize" 81//usage: "\n -n Run in foreground"
82//usage: "\n -q Quit after clock is set" 82//usage: "\n -q Quit after clock is set"
83//usage: "\n -N Run at high priority" 83//usage: "\n -N Run at high priority"
84//usage: "\n -w Do not set time (only query peers), implies -n" 84//usage: "\n -w Do not set time (only query peers), implies -n"
@@ -1152,7 +1152,7 @@ fit(peer_t *p, double rd)
1152// return 0; 1152// return 0;
1153 return 1; 1153 return 1;
1154} 1154}
1155static peer_t* 1155static NOINLINE peer_t*
1156select_and_cluster(void) 1156select_and_cluster(void)
1157{ 1157{
1158 peer_t *p; 1158 peer_t *p;
diff --git a/networking/tls.c b/networking/tls.c
index a1b12f9ed..36f83212b 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -22,47 +22,23 @@
22 22
23#include "tls.h" 23#include "tls.h"
24 24
25// Usually enabled. You can disable some of them to force only
26// specific ciphers to be advertized to server.
27// (this would not exclude code to handle disabled ciphers, no code size win)
28#define ALLOW_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 1
29#define ALLOW_ECDHE_RSA_WITH_AES_128_CBC_SHA256 1
30#define ALLOW_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 1
31#define ALLOW_ECDHE_RSA_WITH_AES_128_GCM_SHA256 1
32#define ALLOW_RSA_WITH_AES_128_CBC_SHA256 1
33#define ALLOW_RSA_WITH_AES_256_CBC_SHA256 1
34#define ALLOW_RSA_WITH_AES_128_GCM_SHA256 1
35#define ALLOW_CURVE_P256 1
36#define ALLOW_CURVE_X25519 1
37
38// For testing (does everything except encrypting).
25// works against "openssl s_server -cipher NULL" 39// works against "openssl s_server -cipher NULL"
26// and against wolfssl-3.9.10-stable/examples/server/server.c: 40// and against wolfssl-3.9.10-stable/examples/server/server.c:
27#define ALLOW_RSA_NULL_SHA256 0 // for testing (does everything except encrypting) 41#define ALLOW_RSA_NULL_SHA256 0
28
29//Tested against kernel.org:
30//#define CIPHER_ID TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA // ok, recvs SERVER_KEY_EXCHANGE *** matrixssl uses this on my box
31//#define CIPHER_ID TLS_RSA_WITH_AES_256_CBC_SHA256 // ok, no SERVER_KEY_EXCHANGE
32//#define CIPHER_ID TLS_DH_anon_WITH_AES_256_CBC_SHA // SSL_ALERT_HANDSHAKE_FAILURE
33//^^^^^^^^^^^^^^^^^^^^^^^ (tested b/c this one doesn't req server certs... no luck, server refuses it)
34//#define CIPHER_ID TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 // SSL_ALERT_HANDSHAKE_FAILURE
35//#define CIPHER_ID TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 // SSL_ALERT_HANDSHAKE_FAILURE
36//#define CIPHER_ID TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 // ok, recvs SERVER_KEY_EXCHANGE
37//#define CIPHER_ID TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
38//#define CIPHER_ID TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
39//#define CIPHER_ID TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 // SSL_ALERT_HANDSHAKE_FAILURE
40//#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
41//#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 // SSL_ALERT_HANDSHAKE_FAILURE
42//#define CIPHER_ID TLS_RSA_WITH_AES_256_GCM_SHA384 // ok, no SERVER_KEY_EXCHANGE
43//#define CIPHER_ID TLS_RSA_WITH_AES_128_GCM_SHA256 // ok, no SERVER_KEY_EXCHANGE
44
45// works against wolfssl-3.9.10-stable/examples/server/server.c
46// works for kernel.org
47// does not work for cdn.kernel.org (e.g. downloading an actual tarball, not a web page)
48// getting alert 40 "handshake failure" at once
49// with GNU Wget 1.18, they agree on TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xC02F) cipher
50// fail: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -cipher AES256-SHA256
51// fail: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -cipher AES256-GCM-SHA384
52// fail: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -cipher AES128-SHA256
53// ok: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -cipher AES128-GCM-SHA256
54// ok: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -cipher AES128-SHA
55// (TLS_RSA_WITH_AES_128_CBC_SHA - in TLS 1.2 it's mandated to be always supported)
56//#define CIPHER_ID1 TLS_RSA_WITH_AES_256_CBC_SHA256 //0x003D
57// Works with "wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.9.5.tar.xz"
58//#define CIPHER_ID2 TLS_RSA_WITH_AES_128_CBC_SHA //0x002F
59
60// bug #11456:
61// ftp.openbsd.org only supports ECDHE-RSA-AESnnn-GCM-SHAnnn or ECDHE-RSA-CHACHA20-POLY1305
62//#define CIPHER_ID3 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 //0xC02F
63// host is.gd accepts only ECDHE-ECDSA-foo (the simplest which works: ECDHE-ECDSA-AES128-SHA 0xC009)
64//#define CIPHER_ID4 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA //0xC009
65
66 42
67#define TLS_DEBUG 0 43#define TLS_DEBUG 0
68#define TLS_DEBUG_HASH 0 44#define TLS_DEBUG_HASH 0
@@ -1488,9 +1464,20 @@ static ALWAYS_INLINE void fill_handshake_record_hdr(void *buf, unsigned type, un
1488 1464
1489static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni) 1465static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni)
1490{ 1466{
1491#define NUM_CIPHERS (7 + 6 * ENABLE_FEATURE_TLS_SHA1 + ALLOW_RSA_NULL_SHA256) 1467#define NUM_CIPHERS (0 \
1468 + 4 * ENABLE_FEATURE_TLS_SHA1 \
1469 + ALLOW_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 \
1470 + ALLOW_ECDHE_RSA_WITH_AES_128_CBC_SHA256 \
1471 + ALLOW_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 \
1472 + ALLOW_ECDHE_RSA_WITH_AES_128_GCM_SHA256 \
1473 + 2 * ENABLE_FEATURE_TLS_SHA1 \
1474 + ALLOW_RSA_WITH_AES_128_CBC_SHA256 \
1475 + ALLOW_RSA_WITH_AES_256_CBC_SHA256 \
1476 + ALLOW_RSA_WITH_AES_128_GCM_SHA256 \
1477 + ALLOW_RSA_NULL_SHA256 \
1478 )
1492 static const uint8_t ciphers[] = { 1479 static const uint8_t ciphers[] = {
1493 0x00,2 + NUM_CIPHERS*2, //len16_be 1480 0x00,2 * (1 + NUM_CIPHERS), //len16_be
1494 0x00,0xFF, //not a cipher - TLS_EMPTY_RENEGOTIATION_INFO_SCSV 1481 0x00,0xFF, //not a cipher - TLS_EMPTY_RENEGOTIATION_INFO_SCSV
1495 /* ^^^^^^ RFC 5746 Renegotiation Indication Extension - some servers will refuse to work with us otherwise */ 1482 /* ^^^^^^ RFC 5746 Renegotiation Indication Extension - some servers will refuse to work with us otherwise */
1496#if ENABLE_FEATURE_TLS_SHA1 1483#if ENABLE_FEATURE_TLS_SHA1
@@ -1501,14 +1488,22 @@ static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni)
1501 // 0xC0,0x18, // TLS_ECDH_anon_WITH_AES_128_CBC_SHA 1488 // 0xC0,0x18, // TLS_ECDH_anon_WITH_AES_128_CBC_SHA
1502 // 0xC0,0x19, // TLS_ECDH_anon_WITH_AES_256_CBC_SHA 1489 // 0xC0,0x19, // TLS_ECDH_anon_WITH_AES_256_CBC_SHA
1503#endif 1490#endif
1491#if ALLOW_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
1504 0xC0,0x23, // 5 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - ok: wget https://is.gd/ 1492 0xC0,0x23, // 5 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - ok: wget https://is.gd/
1493#endif
1505 // 0xC0,0x24, // TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - can't do SHA384 yet 1494 // 0xC0,0x24, // TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - can't do SHA384 yet
1495#if ALLOW_ECDHE_RSA_WITH_AES_128_CBC_SHA256
1506 0xC0,0x27, // 6 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - ok: openssl s_server ... -cipher ECDHE-RSA-AES128-SHA256 1496 0xC0,0x27, // 6 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - ok: openssl s_server ... -cipher ECDHE-RSA-AES128-SHA256
1497#endif
1507 // 0xC0,0x28, // TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - can't do SHA384 yet 1498 // 0xC0,0x28, // TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - can't do SHA384 yet
1499#if ALLOW_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
1508 0xC0,0x2B, // 7 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - ok: wget https://is.gd/ 1500 0xC0,0x2B, // 7 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - ok: wget https://is.gd/
1501#endif
1509 // 0xC0,0x2C, // TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - wget https://is.gd/: "TLS error from peer (alert code 20): bad MAC" 1502 // 0xC0,0x2C, // TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - wget https://is.gd/: "TLS error from peer (alert code 20): bad MAC"
1510//TODO: GCM_SHA384 ciphers can be supported, only need sha384-based PRF? 1503//TODO: GCM_SHA384 ciphers can be supported, only need sha384-based PRF?
1504#if ALLOW_ECDHE_RSA_WITH_AES_128_GCM_SHA256
1511 0xC0,0x2F, // 8 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - ok: openssl s_server ... -cipher ECDHE-RSA-AES128-GCM-SHA256 1505 0xC0,0x2F, // 8 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - ok: openssl s_server ... -cipher ECDHE-RSA-AES128-GCM-SHA256
1506#endif
1512 // 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" 1507 // 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"
1513 //possibly these too: 1508 //possibly these too:
1514#if ENABLE_FEATURE_TLS_SHA1 1509#if ENABLE_FEATURE_TLS_SHA1
@@ -1521,9 +1516,15 @@ static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni)
1521 0x00,0x2F, // 9 TLS_RSA_WITH_AES_128_CBC_SHA - ok: openssl s_server ... -cipher AES128-SHA 1516 0x00,0x2F, // 9 TLS_RSA_WITH_AES_128_CBC_SHA - ok: openssl s_server ... -cipher AES128-SHA
1522 0x00,0x35, //10 TLS_RSA_WITH_AES_256_CBC_SHA - ok: openssl s_server ... -cipher AES256-SHA 1517 0x00,0x35, //10 TLS_RSA_WITH_AES_256_CBC_SHA - ok: openssl s_server ... -cipher AES256-SHA
1523#endif 1518#endif
1519#if ALLOW_RSA_WITH_AES_128_CBC_SHA256
1524 0x00,0x3C, //11 TLS_RSA_WITH_AES_128_CBC_SHA256 - ok: openssl s_server ... -cipher AES128-SHA256 1520 0x00,0x3C, //11 TLS_RSA_WITH_AES_128_CBC_SHA256 - ok: openssl s_server ... -cipher AES128-SHA256
1521#endif
1522#if ALLOW_RSA_WITH_AES_256_CBC_SHA256
1525 0x00,0x3D, //12 TLS_RSA_WITH_AES_256_CBC_SHA256 - ok: openssl s_server ... -cipher AES256-SHA256 1523 0x00,0x3D, //12 TLS_RSA_WITH_AES_256_CBC_SHA256 - ok: openssl s_server ... -cipher AES256-SHA256
1524#endif
1525#if ALLOW_RSA_WITH_AES_128_GCM_SHA256
1526 0x00,0x9C, //13 TLS_RSA_WITH_AES_128_GCM_SHA256 - ok: openssl s_server ... -cipher AES128-GCM-SHA256 1526 0x00,0x9C, //13 TLS_RSA_WITH_AES_128_GCM_SHA256 - ok: openssl s_server ... -cipher AES128-GCM-SHA256
1527#endif
1527 // 0x00,0x9D, // TLS_RSA_WITH_AES_256_GCM_SHA384 - openssl s_server ... -cipher AES256-GCM-SHA384: "decryption failed or bad record mac" 1528 // 0x00,0x9D, // TLS_RSA_WITH_AES_256_GCM_SHA384 - openssl s_server ... -cipher AES256-GCM-SHA384: "decryption failed or bad record mac"
1528#if ALLOW_RSA_NULL_SHA256 1529#if ALLOW_RSA_NULL_SHA256
1529 0x00,0x3B, // TLS_RSA_WITH_NULL_SHA256 1530 0x00,0x3B, // TLS_RSA_WITH_NULL_SHA256
@@ -1532,12 +1533,16 @@ static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni)
1532 }; 1533 };
1533 static const uint8_t supported_groups[] = { 1534 static const uint8_t supported_groups[] = {
1534 0x00,0x0a, //extension_type: "supported_groups" 1535 0x00,0x0a, //extension_type: "supported_groups"
1535 0x00,0x06, //ext len 1536 0x00,2 * (1 + ALLOW_CURVE_P256 + ALLOW_CURVE_X25519), //ext len
1536 0x00,0x04, //list len 1537 0x00,2 * (0 + ALLOW_CURVE_P256 + ALLOW_CURVE_X25519), //list len
1537 0x00,0x17, //curve_secp256r1 (aka P256) 1538#if ALLOW_CURVE_P256
1539 0x00,0x17, //curve_secp256r1 (aka P256, aka prime256v1)
1540#endif
1538 //0x00,0x18, //curve_secp384r1 1541 //0x00,0x18, //curve_secp384r1
1539 //0x00,0x19, //curve_secp521r1 1542 //0x00,0x19, //curve_secp521r1
1543#if ALLOW_CURVE_X25519
1540 0x00,0x1d, //curve_x25519 (RFC 7748) 1544 0x00,0x1d, //curve_x25519 (RFC 7748)
1545#endif
1541 //0x00,0x1e, //curve_x448 (RFC 7748) 1546 //0x00,0x1e, //curve_x448 (RFC 7748)
1542 }; 1547 };
1543 //static const uint8_t signature_algorithms[] = { 1548 //static const uint8_t signature_algorithms[] = {
@@ -1555,7 +1560,7 @@ static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni)
1555 uint8_t session_id_len; 1560 uint8_t session_id_len;
1556 /* uint8_t session_id[]; */ 1561 /* uint8_t session_id[]; */
1557 uint8_t cipherid_len16_hi, cipherid_len16_lo; 1562 uint8_t cipherid_len16_hi, cipherid_len16_lo;
1558 uint8_t cipherid[2 + NUM_CIPHERS*2]; /* actually variable */ 1563 uint8_t cipherid[2 * (1 + NUM_CIPHERS)]; /* actually variable */
1559 uint8_t comprtypes_len; 1564 uint8_t comprtypes_len;
1560 uint8_t comprtypes[1]; /* actually variable */ 1565 uint8_t comprtypes[1]; /* actually variable */
1561 /* Extensions (SNI shown): 1566 /* Extensions (SNI shown):
@@ -1603,7 +1608,7 @@ static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni)
1603 memset(record->rand32, 0x11, sizeof(record->rand32)); 1608 memset(record->rand32, 0x11, sizeof(record->rand32));
1604 /* record->session_id_len = 0; - already is */ 1609 /* record->session_id_len = 0; - already is */
1605 1610
1606 BUILD_BUG_ON(sizeof(ciphers) != 2 + 2 + NUM_CIPHERS*2 + 2); 1611 BUILD_BUG_ON(sizeof(ciphers) != 2 * (1 + 1 + NUM_CIPHERS + 1));
1607 memcpy(&record->cipherid_len16_hi, ciphers, sizeof(ciphers)); 1612 memcpy(&record->cipherid_len16_hi, ciphers, sizeof(ciphers));
1608 1613
1609 ptr = (void*)(record + 1); 1614 ptr = (void*)(record + 1);
@@ -1700,42 +1705,33 @@ static void get_server_hello(tls_state_t *tls)
1700 1705
1701 /* Set up encryption params based on selected cipher */ 1706 /* Set up encryption params based on selected cipher */
1702#if 0 1707#if 0
1703#if ENABLE_FEATURE_TLS_SHA1
1704 0xC0,0x09, // 1 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - ok: wget https://is.gd/ 1708 0xC0,0x09, // 1 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - ok: wget https://is.gd/
1705 0xC0,0x0A, // 2 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - ok: wget https://is.gd/ 1709 0xC0,0x0A, // 2 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - ok: wget https://is.gd/
1706 0xC0,0x13, // 3 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - ok: openssl s_server ... -cipher ECDHE-RSA-AES128-SHA 1710 0xC0,0x13, // 3 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - ok: openssl s_server ... -cipher ECDHE-RSA-AES128-SHA
1707 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) 1711 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)
1708 // 0xC0,0x18, // TLS_ECDH_anon_WITH_AES_128_CBC_SHA 1712 // 0xC0,0x18, // TLS_ECDH_anon_WITH_AES_128_CBC_SHA
1709 // 0xC0,0x19, // TLS_ECDH_anon_WITH_AES_256_CBC_SHA 1713 // 0xC0,0x19, // TLS_ECDH_anon_WITH_AES_256_CBC_SHA
1710#endif
1711 0xC0,0x23, // 5 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - ok: wget https://is.gd/ 1714 0xC0,0x23, // 5 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - ok: wget https://is.gd/
1712 // 0xC0,0x24, // TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - can't do SHA384 yet 1715 // 0xC0,0x24, // TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - can't do SHA384 yet
1713 0xC0,0x27, // 6 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - ok: openssl s_server ... -cipher ECDHE-RSA-AES128-SHA256 1716 0xC0,0x27, // 6 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - ok: openssl s_server ... -cipher ECDHE-RSA-AES128-SHA256
1714 // 0xC0,0x28, // TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - can't do SHA384 yet 1717 // 0xC0,0x28, // TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - can't do SHA384 yet
1715 0xC0,0x2B, // 7 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - ok: wget https://is.gd/ 1718 0xC0,0x2B, // 7 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - ok: wget https://is.gd/
1716 // 0xC0,0x2C, // TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - wget https://is.gd/: "TLS error from peer (alert code 20): bad MAC" 1719 // 0xC0,0x2C, // TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - wget https://is.gd/: "TLS error from peer (alert code 20): bad MAC"
1717//TODO: GCM_SHA384 ciphers can be supported, only need sha384-based PRF?
1718 0xC0,0x2F, // 8 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - ok: openssl s_server ... -cipher ECDHE-RSA-AES128-GCM-SHA256 1720 0xC0,0x2F, // 8 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - ok: openssl s_server ... -cipher ECDHE-RSA-AES128-GCM-SHA256
1719 // 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" 1721 // 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"
1720 //possibly these too: 1722 //possibly these too:
1721#if ENABLE_FEATURE_TLS_SHA1
1722 // 0xC0,0x35, // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA 1723 // 0xC0,0x35, // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
1723 // 0xC0,0x36, // TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA 1724 // 0xC0,0x36, // TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
1724#endif
1725 // 0xC0,0x37, // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 1725 // 0xC0,0x37, // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
1726 // 0xC0,0x38, // TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 - can't do SHA384 yet 1726 // 0xC0,0x38, // TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 - can't do SHA384 yet
1727#if ENABLE_FEATURE_TLS_SHA1
1728 0x00,0x2F, // 9 TLS_RSA_WITH_AES_128_CBC_SHA - ok: openssl s_server ... -cipher AES128-SHA 1727 0x00,0x2F, // 9 TLS_RSA_WITH_AES_128_CBC_SHA - ok: openssl s_server ... -cipher AES128-SHA
1729 0x00,0x35, //10 TLS_RSA_WITH_AES_256_CBC_SHA - ok: openssl s_server ... -cipher AES256-SHA 1728 0x00,0x35, //10 TLS_RSA_WITH_AES_256_CBC_SHA - ok: openssl s_server ... -cipher AES256-SHA
1730#endif
1731 0x00,0x3C, //11 TLS_RSA_WITH_AES_128_CBC_SHA256 - ok: openssl s_server ... -cipher AES128-SHA256 1729 0x00,0x3C, //11 TLS_RSA_WITH_AES_128_CBC_SHA256 - ok: openssl s_server ... -cipher AES128-SHA256
1732 0x00,0x3D, //12 TLS_RSA_WITH_AES_256_CBC_SHA256 - ok: openssl s_server ... -cipher AES256-SHA256 1730 0x00,0x3D, //12 TLS_RSA_WITH_AES_256_CBC_SHA256 - ok: openssl s_server ... -cipher AES256-SHA256
1733 0x00,0x9C, //13 TLS_RSA_WITH_AES_128_GCM_SHA256 - ok: openssl s_server ... -cipher AES128-GCM-SHA256 1731 0x00,0x9C, //13 TLS_RSA_WITH_AES_128_GCM_SHA256 - ok: openssl s_server ... -cipher AES128-GCM-SHA256
1734 // 0x00,0x9D, // TLS_RSA_WITH_AES_256_GCM_SHA384 - openssl s_server ... -cipher AES256-GCM-SHA384: "decryption failed or bad record mac" 1732 // 0x00,0x9D, // TLS_RSA_WITH_AES_256_GCM_SHA384 - openssl s_server ... -cipher AES256-GCM-SHA384: "decryption failed or bad record mac"
1735#if ALLOW_RSA_NULL_SHA256
1736 0x00,0x3B, // TLS_RSA_WITH_NULL_SHA256 1733 0x00,0x3B, // TLS_RSA_WITH_NULL_SHA256
1737#endif 1734#endif
1738#endif
1739 cipherid1 = cipherid[1]; 1735 cipherid1 = cipherid[1];
1740 tls->cipher_id = 0x100 * cipherid[0] + cipherid1; 1736 tls->cipher_id = 0x100 * cipherid[0] + cipherid1;
1741 tls->key_size = AES256_KEYSIZE; 1737 tls->key_size = AES256_KEYSIZE;
@@ -1944,7 +1940,7 @@ static void send_client_key_exchange(tls_state_t *tls)
1944 if (!(tls->flags & NEED_EC_KEY)) { 1940 if (!(tls->flags & NEED_EC_KEY)) {
1945 /* RSA */ 1941 /* RSA */
1946 if (!(tls->flags & GOT_CERT_RSA_KEY_ALG)) 1942 if (!(tls->flags & GOT_CERT_RSA_KEY_ALG))
1947 bb_simple_error_msg("server cert is not RSA"); 1943 bb_simple_error_msg_and_die("server cert is not RSA");
1948 1944
1949 tls_get_random(premaster, RSA_PREMASTER_SIZE); 1945 tls_get_random(premaster, RSA_PREMASTER_SIZE);
1950 if (TLS_DEBUG_FIXED_SECRETS) 1946 if (TLS_DEBUG_FIXED_SECRETS)
@@ -2330,6 +2326,47 @@ void FAST_FUNC tls_run_copy_loop(tls_state_t *tls, unsigned flags)
2330 const int INBUF_STEP = 4 * 1024; 2326 const int INBUF_STEP = 4 * 1024;
2331 struct pollfd pfds[2]; 2327 struct pollfd pfds[2];
2332 2328
2329#if 0
2330// Debug aid for comparing P256 implementations.
2331// Enable this, set SP_DEBUG and FIXED_SECRET to 1,
2332// and add
2333// tls_run_copy_loop(NULL, 0);
2334// e.g. at the very beginning of wget_main()
2335//
2336{
2337 uint8_t ecc_pub_key32[2 * 32];
2338 uint8_t pubkey2x32[2 * 32];
2339 uint8_t premaster32[32];
2340
2341//Fixed input key:
2342// memset(ecc_pub_key32, 0xee, sizeof(ecc_pub_key32));
2343//Fixed 000000000000000000000000000000000000ab000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2344// memset(ecc_pub_key32, 0x00, sizeof(ecc_pub_key32));
2345// ecc_pub_key32[18] = 0xab;
2346//Random key:
2347// tls_get_random(ecc_pub_key32, sizeof(ecc_pub_key32));
2348//Biased random (almost all zeros or almost all ones):
2349 srand(time(NULL) ^ getpid());
2350 if (rand() & 1)
2351 memset(ecc_pub_key32, 0x00, sizeof(ecc_pub_key32));
2352 else
2353 memset(ecc_pub_key32, 0xff, sizeof(ecc_pub_key32));
2354 ecc_pub_key32[rand() & 0x3f] = rand();
2355
2356 xmove_fd(xopen("p256.OLD", O_WRONLY | O_CREAT | O_TRUNC), 2);
2357 curve_P256_compute_pubkey_and_premaster(
2358 pubkey2x32, premaster32,
2359 /*point:*/ ecc_pub_key32
2360 );
2361 xmove_fd(xopen("p256.NEW", O_WRONLY | O_CREAT | O_TRUNC), 2);
2362 curve_P256_compute_pubkey_and_premaster_NEW(
2363 pubkey2x32, premaster32,
2364 /*point:*/ ecc_pub_key32
2365 );
2366 exit(1);
2367}
2368#endif
2369
2333 pfds[0].fd = STDIN_FILENO; 2370 pfds[0].fd = STDIN_FILENO;
2334 pfds[0].events = POLLIN; 2371 pfds[0].events = POLLIN;
2335 pfds[1].fd = tls->ifd; 2372 pfds[1].fd = tls->ifd;
diff --git a/networking/tls.h b/networking/tls.h
index 215e92b02..0173b87b2 100644
--- a/networking/tls.h
+++ b/networking/tls.h
@@ -101,7 +101,6 @@ void xorbuf_aligned_AES_BLOCK_SIZE(void* buf, const void* mask) FAST_FUNC;
101 101
102 102
103#include "tls_pstm.h" 103#include "tls_pstm.h"
104#include "tls_symmetric.h"
105#include "tls_aes.h" 104#include "tls_aes.h"
106#include "tls_aesgcm.h" 105#include "tls_aesgcm.h"
107#include "tls_rsa.h" 106#include "tls_rsa.h"
@@ -117,3 +116,7 @@ void curve_x25519_compute_pubkey_and_premaster(
117void curve_P256_compute_pubkey_and_premaster( 116void curve_P256_compute_pubkey_and_premaster(
118 uint8_t *pubkey2x32, uint8_t *premaster32, 117 uint8_t *pubkey2x32, uint8_t *premaster32,
119 const uint8_t *peerkey2x32) FAST_FUNC; 118 const uint8_t *peerkey2x32) FAST_FUNC;
119
120void curve_P256_compute_pubkey_and_premaster_NEW(
121 uint8_t *pubkey2x32, uint8_t *premaster32,
122 const uint8_t *peerkey2x32) FAST_FUNC;
diff --git a/networking/tls_fe.c b/networking/tls_fe.c
index ecb410281..3a0a6776f 100644
--- a/networking/tls_fe.c
+++ b/networking/tls_fe.c
@@ -63,16 +63,22 @@ static void fprime_select(byte *dst, const byte *zero, const byte *one, byte con
63} 63}
64#endif 64#endif
65 65
66#if 0 /* constant-time */
66static void fe_select(byte *dst, 67static void fe_select(byte *dst,
67 const byte *zero, const byte *one, 68 const byte *src,
68 byte condition) 69 byte condition)
69{ 70{
70 const byte mask = -condition; 71 const byte mask = -condition;
71 int i; 72 int i;
72 73
73 for (i = 0; i < F25519_SIZE; i++) 74 for (i = 0; i < F25519_SIZE; i++)
74 dst[i] = zero[i] ^ (mask & (one[i] ^ zero[i])); 75 dst[i] = dst[i] ^ (mask & (src[i] ^ dst[i]));
75} 76}
77#else
78# define fe_select(dst, src, condition) do { \
79 if (condition) lm_copy(dst, src); \
80} while (0)
81#endif
76 82
77#if 0 //UNUSED 83#if 0 //UNUSED
78static void raw_add(byte *x, const byte *p) 84static void raw_add(byte *x, const byte *p)
@@ -225,7 +231,7 @@ static void fe_normalize(byte *x)
225 minusp[31] = (byte)c; 231 minusp[31] = (byte)c;
226 232
227 /* Load x-p if no underflow */ 233 /* Load x-p if no underflow */
228 fe_select(x, minusp, x, (c >> 15) & 1); 234 fe_select(x, minusp, !(c & (1<<15)));
229} 235}
230 236
231static void lm_add(byte* r, const byte* a, const byte* b) 237static void lm_add(byte* r, const byte* a, const byte* b)
@@ -548,26 +554,32 @@ static void curve25519(byte *result, const byte *e, const byte *q)
548{ 554{
549 int i; 555 int i;
550 556
551 struct { 557 struct Z {
552 /* for bbox's special case of q == NULL meaning "use basepoint" */ 558 /* for bbox's special case of q == NULL meaning "use basepoint" */
553 /*static const*/ uint8_t basepoint9[CURVE25519_KEYSIZE]; // = {9}; 559 /*static const*/ uint8_t basepoint9[CURVE25519_KEYSIZE]; // = {9};
554 560
555 /* from wolfssl-3.15.3/wolfssl/wolfcrypt/fe_operations.h */ 561 /* from wolfssl-3.15.3/wolfssl/wolfcrypt/fe_operations.h */
556 /*static const*/ byte f25519_one[F25519_SIZE]; // = {1}; 562 /*static const*/ byte f25519_one[F25519_SIZE]; // = {1};
557 563
558 /* Current point: P_m */
559 byte xm[F25519_SIZE];
560 byte zm[F25519_SIZE]; // = {1};
561 /* Predecessor: P_(m-1) */ 564 /* Predecessor: P_(m-1) */
562 byte xm1[F25519_SIZE]; // = {1}; 565 byte xm1[F25519_SIZE]; // = {1};
563 byte zm1[F25519_SIZE]; // = {0}; 566 byte zm1[F25519_SIZE]; // = {0};
567 /* Current point: P_m */
568 byte xm[F25519_SIZE];
569 byte zm[F25519_SIZE]; // = {1};
570 /* Temporaries */
571 byte xms[F25519_SIZE];
572 byte zms[F25519_SIZE];
564 } z; 573 } z;
574 uint8_t *XM1 = (uint8_t*)&z + offsetof(struct Z,xm1); // gcc 11.0.0 workaround
565#define basepoint9 z.basepoint9 575#define basepoint9 z.basepoint9
566#define f25519_one z.f25519_one 576#define f25519_one z.f25519_one
567#define xm z.xm
568#define zm z.zm
569#define xm1 z.xm1 577#define xm1 z.xm1
570#define zm1 z.zm1 578#define zm1 z.zm1
579#define xm z.xm
580#define zm z.zm
581#define xms z.xms
582#define zms z.zms
571 memset(&z, 0, sizeof(z)); 583 memset(&z, 0, sizeof(z));
572 f25519_one[0] = 1; 584 f25519_one[0] = 1;
573 zm[0] = 1; 585 zm[0] = 1;
@@ -583,8 +595,8 @@ static void curve25519(byte *result, const byte *e, const byte *q)
583 595
584 for (i = 253; i >= 0; i--) { 596 for (i = 253; i >= 0; i--) {
585 const int bit = (e[i >> 3] >> (i & 7)) & 1; 597 const int bit = (e[i >> 3] >> (i & 7)) & 1;
586 byte xms[F25519_SIZE]; 598// byte xms[F25519_SIZE];
587 byte zms[F25519_SIZE]; 599// byte zms[F25519_SIZE];
588 600
589 /* From P_m and P_(m-1), compute P_(2m) and P_(2m-1) */ 601 /* From P_m and P_(m-1), compute P_(2m) and P_(2m-1) */
590 xc_diffadd(xm1, zm1, q, f25519_one, xm, zm, xm1, zm1); 602 xc_diffadd(xm1, zm1, q, f25519_one, xm, zm, xm1, zm1);
@@ -597,10 +609,22 @@ static void curve25519(byte *result, const byte *e, const byte *q)
597 * bit = 1 --> (P_(2m+1), P_(2m)) 609 * bit = 1 --> (P_(2m+1), P_(2m))
598 * bit = 0 --> (P_(2m), P_(2m-1)) 610 * bit = 0 --> (P_(2m), P_(2m-1))
599 */ 611 */
600 fe_select(xm1, xm1, xm, bit); 612#if 0
601 fe_select(zm1, zm1, zm, bit); 613 fe_select(xm1, xm, bit);
602 fe_select(xm, xm, xms, bit); 614 fe_select(zm1, zm, bit);
603 fe_select(zm, zm, zms, bit); 615 fe_select(xm, xms, bit);
616 fe_select(zm, zms, bit);
617#else
618// same as above in about 50 bytes smaller code, but
619// requires that in-memory order is exactly xm1,zm1,xm,zm,xms,zms
620 if (bit) {
621 //memcpy(xm1, xm, 4 * F25519_SIZE);
622 //^^^ gcc 11.0.0 warns of overlapping memcpy
623 //memmove(xm1, xm, 4 * F25519_SIZE);
624 //^^^ gcc 11.0.0 warns of out-of-bounds access to xm1[]
625 memmove(XM1, XM1 + 2 * F25519_SIZE, 4 * F25519_SIZE);
626 }
627#endif
604 } 628 }
605 629
606 /* Freeze out of projective coordinates */ 630 /* Freeze out of projective coordinates */
diff --git a/networking/tls_pstm.h b/networking/tls_pstm.h
index bc7a0119a..56c6bb879 100644
--- a/networking/tls_pstm.h
+++ b/networking/tls_pstm.h
@@ -283,4 +283,3 @@ extern int32 pstm_invmod(psPool_t *pool, pstm_int * a, pstm_int * b,
283 typedef int32 pstm_int; 283 typedef int32 pstm_int;
284#endif /* !DISABLE_PSTM */ 284#endif /* !DISABLE_PSTM */
285#endif /* _h_PSTMATH */ 285#endif /* _h_PSTMATH */
286
diff --git a/networking/tls_sp_c32.c b/networking/tls_sp_c32.c
index 5a84852a5..4d4ecdd74 100644
--- a/networking/tls_sp_c32.c
+++ b/networking/tls_sp_c32.c
@@ -9,6 +9,8 @@
9#define FIXED_SECRET 0 9#define FIXED_SECRET 0
10#define FIXED_PEER_PUBKEY 0 10#define FIXED_PEER_PUBKEY 0
11 11
12#define ALLOW_ASM 1
13
12#if SP_DEBUG 14#if SP_DEBUG
13# define dbg(...) fprintf(stderr, __VA_ARGS__) 15# define dbg(...) fprintf(stderr, __VA_ARGS__)
14static void dump_hex(const char *fmt, const void *vp, int len) 16static void dump_hex(const char *fmt, const void *vp, int len)
@@ -24,127 +26,98 @@ static void dump_hex(const char *fmt, const void *vp, int len)
24# define dump_hex(...) ((void)0) 26# define dump_hex(...) ((void)0)
25#endif 27#endif
26 28
27#undef DIGIT_BIT 29typedef uint32_t sp_digit;
28#define DIGIT_BIT 32 30typedef int32_t signed_sp_digit;
29typedef int32_t sp_digit;
30 31
31/* The code below is taken from parts of 32/* The code below is taken from parts of
32 * wolfssl-3.15.3/wolfcrypt/src/sp_c32.c 33 * wolfssl-3.15.3/wolfcrypt/src/sp_c32.c
33 * and heavily modified. 34 * and heavily modified.
34 * Header comment is kept intact:
35 */ 35 */
36 36
37/* sp.c
38 *
39 * Copyright (C) 2006-2018 wolfSSL Inc.
40 *
41 * This file is part of wolfSSL.
42 *
43 * wolfSSL is free software; you can redistribute it and/or modify
44 * it under the terms of the GNU General Public License as published by
45 * the Free Software Foundation; either version 2 of the License, or
46 * (at your option) any later version.
47 *
48 * wolfSSL is distributed in the hope that it will be useful,
49 * but WITHOUT ANY WARRANTY; without even the implied warranty of
50 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
51 * GNU General Public License for more details.
52 *
53 * You should have received a copy of the GNU General Public License
54 * along with this program; if not, write to the Free Software
55 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
56 */
57
58/* Implementation by Sean Parkinson. */
59
60typedef struct sp_point { 37typedef struct sp_point {
61 sp_digit x[2 * 10]; 38 sp_digit x[2 * 8];
62 sp_digit y[2 * 10]; 39 sp_digit y[2 * 8];
63 sp_digit z[2 * 10]; 40 sp_digit z[2 * 8];
64 int infinity; 41 int infinity;
65} sp_point; 42} sp_point;
66 43
67/* The modulus (prime) of the curve P256. */ 44/* The modulus (prime) of the curve P256. */
68static const sp_digit p256_mod[10] = { 45static const sp_digit p256_mod[8] = {
69 0x3ffffff,0x3ffffff,0x3ffffff,0x003ffff,0x0000000, 46 0xffffffff,0xffffffff,0xffffffff,0x00000000,
70 0x0000000,0x0000000,0x0000400,0x3ff0000,0x03fffff, 47 0x00000000,0x00000000,0x00000001,0xffffffff,
71}; 48};
72 49
73#define p256_mp_mod ((sp_digit)0x000001) 50#define p256_mp_mod ((sp_digit)0x000001)
74 51
75/* Write r as big endian to byte aray. 52/* Normalize the values in each word to 32 bits - NOP */
53#define sp_256_norm_8(a) ((void)0)
54
55/* Write r as big endian to byte array.
76 * Fixed length number of bytes written: 32 56 * Fixed length number of bytes written: 32
77 * 57 *
78 * r A single precision integer. 58 * r A single precision integer.
79 * a Byte array. 59 * a Byte array.
80 */ 60 */
81static void sp_256_to_bin(sp_digit* r, uint8_t* a) 61static void sp_256_to_bin_8(const sp_digit* r, uint8_t* a)
82{ 62{
83 int i, j, s = 0, b; 63 int i;
84 64
85 for (i = 0; i < 9; i++) { 65 sp_256_norm_8(r);
86 r[i+1] += r[i] >> 26; 66
87 r[i] &= 0x3ffffff; 67 r += 8;
88 } 68 for (i = 0; i < 8; i++) {
89 j = 256 / 8 - 1; 69 r--;
90 a[j] = 0; 70 move_to_unaligned32(a, SWAP_BE32(*r));
91 for (i = 0; i < 10 && j >= 0; i++) { 71 a += 4;
92 b = 0;
93 a[j--] |= r[i] << s; b += 8 - s;
94 if (j < 0)
95 break;
96 while (b < 26) {
97 a[j--] = r[i] >> b; b += 8;
98 if (j < 0)
99 break;
100 }
101 s = 8 - (b - 26);
102 if (j >= 0)
103 a[j] = 0;
104 if (s != 0)
105 j++;
106 } 72 }
107} 73}
108 74
109/* Read big endian unsigned byte aray into r. 75/* Read big endian unsigned byte array into r.
110 * 76 *
111 * r A single precision integer. 77 * r A single precision integer.
112 * a Byte array. 78 * a Byte array.
113 * n Number of bytes in array to read. 79 * n Number of bytes in array to read.
114 */ 80 */
115static void sp_256_from_bin(sp_digit* r, int max, const uint8_t* a, int n) 81static void sp_256_from_bin_8(sp_digit* r, const uint8_t* a)
116{ 82{
117 int i, j = 0, s = 0; 83 int i;
118 84
119 r[0] = 0; 85 r += 8;
120 for (i = n-1; i >= 0; i--) { 86 for (i = 0; i < 8; i++) {
121 r[j] |= ((sp_digit)a[i]) << s; 87 sp_digit v;
122 if (s >= 18) { 88 move_from_unaligned32(v, a);
123 r[j] &= 0x3ffffff; 89 *--r = SWAP_BE32(v);
124 s = 26 - s; 90 a += 4;
125 if (j + 1 >= max)
126 break;
127 r[++j] = a[i] >> s;
128 s = 8 - s;
129 }
130 else
131 s += 8;
132 } 91 }
92}
133 93
134 for (j++; j < max; j++) 94#if SP_DEBUG
135 r[j] = 0; 95static void dump_256(const char *fmt, const sp_digit* r)
96{
97 uint8_t b32[32];
98 sp_256_to_bin_8(r, b32);
99 dump_hex(fmt, b32, 32);
100}
101static void dump_512(const char *fmt, const sp_digit* r)
102{
103 uint8_t b64[64];
104 sp_256_to_bin_8(r, b64 + 32);
105 sp_256_to_bin_8(r+8, b64);
106 dump_hex(fmt, b64, 64);
136} 107}
108#else
109# define dump_256(...) ((void)0)
110# define dump_512(...) ((void)0)
111#endif
137 112
138/* Convert a point of big-endian 32-byte x,y pair to type sp_point. */ 113/* Convert a point of big-endian 32-byte x,y pair to type sp_point. */
139static void sp_256_point_from_bin2x32(sp_point* p, const uint8_t *bin2x32) 114static void sp_256_point_from_bin2x32(sp_point* p, const uint8_t *bin2x32)
140{ 115{
141 memset(p, 0, sizeof(*p)); 116 memset(p, 0, sizeof(*p));
142 /*p->infinity = 0;*/ 117 /*p->infinity = 0;*/
143 sp_256_from_bin(p->x, 2 * 10, bin2x32, 32); 118 sp_256_from_bin_8(p->x, bin2x32);
144 sp_256_from_bin(p->y, 2 * 10, bin2x32 + 32, 32); 119 sp_256_from_bin_8(p->y, bin2x32 + 32);
145 //static const uint8_t one[1] = { 1 }; 120 p->z[0] = 1; /* p->z = 1 */
146 //sp_256_from_bin(p->z, 2 * 10, one, 1);
147 p->z[0] = 1;
148} 121}
149 122
150/* Compare a with b. 123/* Compare a with b.
@@ -152,201 +125,650 @@ static void sp_256_point_from_bin2x32(sp_point* p, const uint8_t *bin2x32)
152 * return -ve, 0 or +ve if a is less than, equal to or greater than b 125 * return -ve, 0 or +ve if a is less than, equal to or greater than b
153 * respectively. 126 * respectively.
154 */ 127 */
155static sp_digit sp_256_cmp_10(const sp_digit* a, const sp_digit* b) 128static signed_sp_digit sp_256_cmp_8(const sp_digit* a, const sp_digit* b)
156{ 129{
157 sp_digit r;
158 int i; 130 int i;
159 for (i = 9; i >= 0; i--) { 131 for (i = 7; i >= 0; i--) {
160 r = a[i] - b[i]; 132/* signed_sp_digit r = a[i] - b[i];
161 if (r != 0) 133 * if (r != 0)
162 break; 134 * return r;
135 * does not work: think about a[i]=0, b[i]=0xffffffff
136 */
137 if (a[i] == b[i])
138 continue;
139 return (a[i] > b[i]) * 2 - 1;
163 } 140 }
164 return r; 141 return 0;
165} 142}
166 143
167/* Compare two numbers to determine if they are equal. 144/* Compare two numbers to determine if they are equal.
168 * 145 *
169 * return 1 when equal and 0 otherwise. 146 * return 1 when equal and 0 otherwise.
170 */ 147 */
171static int sp_256_cmp_equal_10(const sp_digit* a, const sp_digit* b) 148static int sp_256_cmp_equal_8(const sp_digit* a, const sp_digit* b)
172{ 149{
173 return sp_256_cmp_10(a, b) == 0; 150 return sp_256_cmp_8(a, b) == 0;
174} 151}
175 152
176/* Normalize the values in each word to 26 bits. */ 153/* Add b to a into r. (r = a + b). Return !0 on overflow */
177static void sp_256_norm_10(sp_digit* a) 154static int sp_256_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b)
178{ 155{
156#if ALLOW_ASM && defined(__GNUC__) && defined(__i386__)
157 sp_digit reg;
158 asm volatile (
159"\n movl (%0), %3"
160"\n addl (%1), %3"
161"\n movl %3, (%2)"
162"\n"
163"\n movl 1*4(%0), %3"
164"\n adcl 1*4(%1), %3"
165"\n movl %3, 1*4(%2)"
166"\n"
167"\n movl 2*4(%0), %3"
168"\n adcl 2*4(%1), %3"
169"\n movl %3, 2*4(%2)"
170"\n"
171"\n movl 3*4(%0), %3"
172"\n adcl 3*4(%1), %3"
173"\n movl %3, 3*4(%2)"
174"\n"
175"\n movl 4*4(%0), %3"
176"\n adcl 4*4(%1), %3"
177"\n movl %3, 4*4(%2)"
178"\n"
179"\n movl 5*4(%0), %3"
180"\n adcl 5*4(%1), %3"
181"\n movl %3, 5*4(%2)"
182"\n"
183"\n movl 6*4(%0), %3"
184"\n adcl 6*4(%1), %3"
185"\n movl %3, 6*4(%2)"
186"\n"
187"\n movl 7*4(%0), %3"
188"\n adcl 7*4(%1), %3"
189"\n movl %3, 7*4(%2)"
190"\n"
191"\n sbbl %3, %3"
192"\n"
193 : "=r" (a), "=r" (b), "=r" (r), "=r" (reg)
194 : "0" (a), "1" (b), "2" (r)
195 : "memory"
196 );
197 return reg;
198#elif ALLOW_ASM && defined(__GNUC__) && defined(__x86_64__)
199 /* x86_64 has no alignment restrictions, and is little-endian,
200 * so 64-bit and 32-bit representations are identical */
201 uint64_t reg;
202 asm volatile (
203"\n movq (%0), %3"
204"\n addq (%1), %3"
205"\n movq %3, (%2)"
206"\n"
207"\n movq 1*8(%0), %3"
208"\n adcq 1*8(%1), %3"
209"\n movq %3, 1*8(%2)"
210"\n"
211"\n movq 2*8(%0), %3"
212"\n adcq 2*8(%1), %3"
213"\n movq %3, 2*8(%2)"
214"\n"
215"\n movq 3*8(%0), %3"
216"\n adcq 3*8(%1), %3"
217"\n movq %3, 3*8(%2)"
218"\n"
219"\n sbbq %3, %3"
220"\n"
221 : "=r" (a), "=r" (b), "=r" (r), "=r" (reg)
222 : "0" (a), "1" (b), "2" (r)
223 : "memory"
224 );
225 return reg;
226#else
179 int i; 227 int i;
180 for (i = 0; i < 9; i++) { 228 sp_digit carry;
181 a[i+1] += a[i] >> 26; 229
182 a[i] &= 0x3ffffff; 230 carry = 0;
231 for (i = 0; i < 8; i++) {
232 sp_digit w, v;
233 w = b[i] + carry;
234 v = a[i];
235 if (w != 0) {
236 v = a[i] + w;
237 carry = (v < a[i]);
238 /* hope compiler detects above as "carry flag set" */
239 }
240 /* else: b + carry == 0, two cases:
241 * b:ffffffff, carry:1
242 * b:00000000, carry:0
243 * in either case, r[i] = a[i] and carry remains unchanged
244 */
245 r[i] = v;
183 } 246 }
247 return carry;
248#endif
184} 249}
185 250
186/* Add b to a into r. (r = a + b) */ 251/* Sub b from a into r. (r = a - b). Return !0 on underflow */
187static void sp_256_add_10(sp_digit* r, const sp_digit* a, const sp_digit* b) 252static int sp_256_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b)
188{ 253{
254#if ALLOW_ASM && defined(__GNUC__) && defined(__i386__)
255 sp_digit reg;
256 asm volatile (
257"\n movl (%0), %3"
258"\n subl (%1), %3"
259"\n movl %3, (%2)"
260"\n"
261"\n movl 1*4(%0), %3"
262"\n sbbl 1*4(%1), %3"
263"\n movl %3, 1*4(%2)"
264"\n"
265"\n movl 2*4(%0), %3"
266"\n sbbl 2*4(%1), %3"
267"\n movl %3, 2*4(%2)"
268"\n"
269"\n movl 3*4(%0), %3"
270"\n sbbl 3*4(%1), %3"
271"\n movl %3, 3*4(%2)"
272"\n"
273"\n movl 4*4(%0), %3"
274"\n sbbl 4*4(%1), %3"
275"\n movl %3, 4*4(%2)"
276"\n"
277"\n movl 5*4(%0), %3"
278"\n sbbl 5*4(%1), %3"
279"\n movl %3, 5*4(%2)"
280"\n"
281"\n movl 6*4(%0), %3"
282"\n sbbl 6*4(%1), %3"
283"\n movl %3, 6*4(%2)"
284"\n"
285"\n movl 7*4(%0), %3"
286"\n sbbl 7*4(%1), %3"
287"\n movl %3, 7*4(%2)"
288"\n"
289"\n sbbl %3, %3"
290"\n"
291 : "=r" (a), "=r" (b), "=r" (r), "=r" (reg)
292 : "0" (a), "1" (b), "2" (r)
293 : "memory"
294 );
295 return reg;
296#elif ALLOW_ASM && defined(__GNUC__) && defined(__x86_64__)
297 /* x86_64 has no alignment restrictions, and is little-endian,
298 * so 64-bit and 32-bit representations are identical */
299 uint64_t reg;
300 asm volatile (
301"\n movq (%0), %3"
302"\n subq (%1), %3"
303"\n movq %3, (%2)"
304"\n"
305"\n movq 1*8(%0), %3"
306"\n sbbq 1*8(%1), %3"
307"\n movq %3, 1*8(%2)"
308"\n"
309"\n movq 2*8(%0), %3"
310"\n sbbq 2*8(%1), %3"
311"\n movq %3, 2*8(%2)"
312"\n"
313"\n movq 3*8(%0), %3"
314"\n sbbq 3*8(%1), %3"
315"\n movq %3, 3*8(%2)"
316"\n"
317"\n sbbq %3, %3"
318"\n"
319 : "=r" (a), "=r" (b), "=r" (r), "=r" (reg)
320 : "0" (a), "1" (b), "2" (r)
321 : "memory"
322 );
323 return reg;
324#else
189 int i; 325 int i;
190 for (i = 0; i < 10; i++) 326 sp_digit borrow;
191 r[i] = a[i] + b[i]; 327
328 borrow = 0;
329 for (i = 0; i < 8; i++) {
330 sp_digit w, v;
331 w = b[i] + borrow;
332 v = a[i];
333 if (w != 0) {
334 v = a[i] - w;
335 borrow = (v > a[i]);
336 /* hope compiler detects above as "carry flag set" */
337 }
338 /* else: b + borrow == 0, two cases:
339 * b:ffffffff, borrow:1
340 * b:00000000, borrow:0
341 * in either case, r[i] = a[i] and borrow remains unchanged
342 */
343 r[i] = v;
344 }
345 return borrow;
346#endif
192} 347}
193 348
194/* Sub b from a into r. (r = a - b) */ 349/* Sub p256_mod from r. (r = r - p256_mod). */
195static void sp_256_sub_10(sp_digit* r, const sp_digit* a, const sp_digit* b) 350#if ALLOW_ASM && defined(__GNUC__) && defined(__i386__)
351static void sp_256_sub_8_p256_mod(sp_digit* r)
196{ 352{
197 int i; 353//p256_mod[7..0] = ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff
198 for (i = 0; i < 10; i++) 354 asm volatile (
199 r[i] = a[i] - b[i]; 355"\n subl $0xffffffff, (%0)"
356"\n sbbl $0xffffffff, 1*4(%0)"
357"\n sbbl $0xffffffff, 2*4(%0)"
358"\n sbbl $0, 3*4(%0)"
359"\n sbbl $0, 4*4(%0)"
360"\n sbbl $0, 5*4(%0)"
361"\n sbbl $1, 6*4(%0)"
362"\n sbbl $0xffffffff, 7*4(%0)"
363"\n"
364 : "=r" (r)
365 : "0" (r)
366 : "memory"
367 );
200} 368}
201 369#elif ALLOW_ASM && defined(__GNUC__) && defined(__x86_64__)
202/* Shift number left one bit. Bottom bit is lost. */ 370static void sp_256_sub_8_p256_mod(sp_digit* r)
203static void sp_256_rshift1_10(sp_digit* r, sp_digit* a)
204{ 371{
205 int i; 372 uint64_t reg;
206 for (i = 0; i < 9; i++) 373 uint64_t ooff;
207 r[i] = ((a[i] >> 1) | (a[i + 1] << 25)) & 0x3ffffff; 374//p256_mod[3..0] = ffffffff00000001 0000000000000000 00000000ffffffff ffffffffffffffff
208 r[9] = a[9] >> 1; 375 asm volatile (
376"\n addq $1, (%0)" // adding 1 is the same as subtracting ffffffffffffffff
377"\n cmc" // only carry bit needs inverting
378"\n"
379"\n sbbq %1, 1*8(%0)" // %1 holds 00000000ffffffff
380"\n"
381"\n sbbq $0, 2*8(%0)"
382"\n"
383"\n movq 3*8(%0), %2"
384"\n sbbq $0, %2" // adding 00000000ffffffff (in %1)
385"\n addq %1, %2" // is the same as subtracting ffffffff00000001
386"\n movq %2, 3*8(%0)"
387"\n"
388 : "=r" (r), "=r" (ooff), "=r" (reg)
389 : "0" (r), "1" (0x00000000ffffffff)
390 : "memory"
391 );
209} 392}
210 393#else
211/* Mul a by scalar b and add into r. (r += a * b) */ 394static void sp_256_sub_8_p256_mod(sp_digit* r)
212static void sp_256_mul_add_10(sp_digit* r, const sp_digit* a, sp_digit b)
213{ 395{
214 int64_t tb = b; 396 sp_256_sub_8(r, r, p256_mod);
215 int64_t t = 0;
216 int i;
217
218 for (i = 0; i < 10; i++) {
219 t += (tb * a[i]) + r[i];
220 r[i] = t & 0x3ffffff;
221 t >>= 26;
222 }
223 r[10] += t;
224} 397}
398#endif
225 399
226/* Multiply a and b into r. (r = a * b) */ 400/* Multiply a and b into r. (r = a * b) */
227static void sp_256_mul_10(sp_digit* r, const sp_digit* a, const sp_digit* b) 401static void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b)
228{ 402{
403#if ALLOW_ASM && defined(__GNUC__) && defined(__i386__)
404 sp_digit rr[15]; /* in case r coincides with a or b */
405 int k;
406 uint32_t accl;
407 uint32_t acch;
408
409 acch = accl = 0;
410 for (k = 0; k < 15; k++) {
411 int i, j;
412 uint32_t acc_hi;
413 i = k - 7;
414 if (i < 0)
415 i = 0;
416 j = k - i;
417 acc_hi = 0;
418 do {
419////////////////////////
420// uint64_t m = ((uint64_t)a[i]) * b[j];
421// acc_hi:acch:accl += m;
422 asm volatile (
423 // a[i] is already loaded in %%eax
424"\n mull %7"
425"\n addl %%eax, %0"
426"\n adcl %%edx, %1"
427"\n adcl $0, %2"
428 : "=rm" (accl), "=rm" (acch), "=rm" (acc_hi)
429 : "0" (accl), "1" (acch), "2" (acc_hi), "a" (a[i]), "m" (b[j])
430 : "cc", "dx"
431 );
432////////////////////////
433 j--;
434 i++;
435 } while (i != 8 && i <= k);
436 rr[k] = accl;
437 accl = acch;
438 acch = acc_hi;
439 }
440 r[15] = accl;
441 memcpy(r, rr, sizeof(rr));
442#elif ALLOW_ASM && defined(__GNUC__) && defined(__x86_64__)
443 /* x86_64 has no alignment restrictions, and is little-endian,
444 * so 64-bit and 32-bit representations are identical */
445 const uint64_t* aa = (const void*)a;
446 const uint64_t* bb = (const void*)b;
447 uint64_t rr[8];
448 int k;
449 uint64_t accl;
450 uint64_t acch;
451
452 acch = accl = 0;
453 for (k = 0; k < 7; k++) {
454 int i, j;
455 uint64_t acc_hi;
456 i = k - 3;
457 if (i < 0)
458 i = 0;
459 j = k - i;
460 acc_hi = 0;
461 do {
462////////////////////////
463// uint128_t m = ((uint128_t)a[i]) * b[j];
464// acc_hi:acch:accl += m;
465 asm volatile (
466 // aa[i] is already loaded in %%rax
467"\n mulq %7"
468"\n addq %%rax, %0"
469"\n adcq %%rdx, %1"
470"\n adcq $0, %2"
471 : "=rm" (accl), "=rm" (acch), "=rm" (acc_hi)
472 : "0" (accl), "1" (acch), "2" (acc_hi), "a" (aa[i]), "m" (bb[j])
473 : "cc", "dx"
474 );
475////////////////////////
476 j--;
477 i++;
478 } while (i != 4 && i <= k);
479 rr[k] = accl;
480 accl = acch;
481 acch = acc_hi;
482 }
483 rr[7] = accl;
484 memcpy(r, rr, sizeof(rr));
485#elif 0
486 //TODO: arm assembly (untested)
487 sp_digit tmp[16];
488
489 asm volatile (
490"\n mov r5, #0"
491"\n mov r6, #0"
492"\n mov r7, #0"
493"\n mov r8, #0"
494"\n 1:"
495"\n subs r3, r5, #28"
496"\n movcc r3, #0"
497"\n sub r4, r5, r3"
498"\n 2:"
499"\n ldr r14, [%[a], r3]"
500"\n ldr r12, [%[b], r4]"
501"\n umull r9, r10, r14, r12"
502"\n adds r6, r6, r9"
503"\n adcs r7, r7, r10"
504"\n adc r8, r8, #0"
505"\n add r3, r3, #4"
506"\n sub r4, r4, #4"
507"\n cmp r3, #32"
508"\n beq 3f"
509"\n cmp r3, r5"
510"\n ble 2b"
511"\n 3:"
512"\n str r6, [%[r], r5]"
513"\n mov r6, r7"
514"\n mov r7, r8"
515"\n mov r8, #0"
516"\n add r5, r5, #4"
517"\n cmp r5, #56"
518"\n ble 1b"
519"\n str r6, [%[r], r5]"
520 : [r] "r" (tmp), [a] "r" (a), [b] "r" (b)
521 : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12", "r14"
522 );
523 memcpy(r, tmp, sizeof(tmp));
524#else
525 sp_digit rr[15]; /* in case r coincides with a or b */
229 int i, j, k; 526 int i, j, k;
230 int64_t c; 527 uint64_t acc;
231 528
232 c = ((int64_t)a[9]) * b[9]; 529 acc = 0;
233 r[19] = (sp_digit)(c >> 26); 530 for (k = 0; k < 15; k++) {
234 c = (c & 0x3ffffff) << 26; 531 uint32_t acc_hi;
235 for (k = 17; k >= 0; k--) { 532 i = k - 7;
236 for (i = 9; i >= 0; i--) { 533 if (i < 0)
237 j = k - i; 534 i = 0;
238 if (j >= 10) 535 j = k - i;
239 break; 536 acc_hi = 0;
240 if (j < 0) 537 do {
241 continue; 538 uint64_t m = ((uint64_t)a[i]) * b[j];
242 c += ((int64_t)a[i]) * b[j]; 539 acc += m;
243 } 540 if (acc < m)
244 r[k + 2] += c >> 52; 541 acc_hi++;
245 r[k + 1] = (c >> 26) & 0x3ffffff; 542 j--;
246 c = (c & 0x3ffffff) << 26; 543 i++;
544 } while (i != 8 && i <= k);
545 rr[k] = acc;
546 acc = (acc >> 32) | ((uint64_t)acc_hi << 32);
247 } 547 }
248 r[0] = (sp_digit)(c >> 26); 548 r[15] = acc;
549 memcpy(r, rr, sizeof(rr));
550#endif
249} 551}
250 552
251/* Square a and put result in r. (r = a * a) */ 553/* Shift number right one bit. Bottom bit is lost. */
252static void sp_256_sqr_10(sp_digit* r, const sp_digit* a) 554static void sp_256_rshift1_8(sp_digit* r, sp_digit* a, sp_digit carry)
253{ 555{
254 int i, j, k; 556 int i;
255 int64_t c; 557
256 558 carry = (!!carry << 31);
257 c = ((int64_t)a[9]) * a[9]; 559 for (i = 7; i >= 0; i--) {
258 r[19] = (sp_digit)(c >> 26); 560 sp_digit c = a[i] << 31;
259 c = (c & 0x3ffffff) << 26; 561 r[i] = (a[i] >> 1) | carry;
260 for (k = 17; k >= 0; k--) { 562 carry = c;
261 for (i = 9; i >= 0; i--) {
262 j = k - i;
263 if (j >= 10 || i <= j)
264 break;
265 if (j < 0)
266 continue;
267 c += ((int64_t)a[i]) * a[j] * 2;
268 }
269 if (i == j)
270 c += ((int64_t)a[i]) * a[i];
271 r[k + 2] += c >> 52;
272 r[k + 1] = (c >> 26) & 0x3ffffff;
273 c = (c & 0x3ffffff) << 26;
274 } 563 }
275 r[0] = (sp_digit)(c >> 26);
276} 564}
277 565
278/* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) */ 566/* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) */
279static void sp_256_div2_10(sp_digit* r, const sp_digit* a, const sp_digit* m) 567static void sp_256_div2_8(sp_digit* r, const sp_digit* a, const sp_digit* m)
280{ 568{
569 int carry = 0;
281 if (a[0] & 1) 570 if (a[0] & 1)
282 sp_256_add_10(r, a, m); 571 carry = sp_256_add_8(r, a, m);
283 sp_256_norm_10(r); 572 sp_256_norm_8(r);
284 sp_256_rshift1_10(r, r); 573 sp_256_rshift1_8(r, r, carry);
285} 574}
286 575
287/* Add two Montgomery form numbers (r = a + b % m) */ 576/* Add two Montgomery form numbers (r = a + b % m) */
288static void sp_256_mont_add_10(sp_digit* r, const sp_digit* a, const sp_digit* b, 577static void sp_256_mont_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b
289 const sp_digit* m) 578 /*, const sp_digit* m*/)
290{ 579{
291 sp_256_add_10(r, a, b); 580// const sp_digit* m = p256_mod;
292 sp_256_norm_10(r); 581
293 if ((r[9] >> 22) > 0) 582 int carry = sp_256_add_8(r, a, b);
294 sp_256_sub_10(r, r, m); 583 sp_256_norm_8(r);
295 sp_256_norm_10(r); 584 if (carry) {
585 sp_256_sub_8_p256_mod(r);
586 sp_256_norm_8(r);
587 }
296} 588}
297 589
298/* Subtract two Montgomery form numbers (r = a - b % m) */ 590/* Subtract two Montgomery form numbers (r = a - b % m) */
299static void sp_256_mont_sub_10(sp_digit* r, const sp_digit* a, const sp_digit* b, 591static void sp_256_mont_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b
300 const sp_digit* m) 592 /*, const sp_digit* m*/)
301{ 593{
302 sp_256_sub_10(r, a, b); 594 const sp_digit* m = p256_mod;
303 if (r[9] >> 22) 595
304 sp_256_add_10(r, r, m); 596 int borrow;
305 sp_256_norm_10(r); 597 borrow = sp_256_sub_8(r, a, b);
598 sp_256_norm_8(r);
599 if (borrow) {
600 sp_256_add_8(r, r, m);
601 sp_256_norm_8(r);
602 }
306} 603}
307 604
308/* Double a Montgomery form number (r = a + a % m) */ 605/* Double a Montgomery form number (r = a + a % m) */
309static void sp_256_mont_dbl_10(sp_digit* r, const sp_digit* a, const sp_digit* m) 606static void sp_256_mont_dbl_8(sp_digit* r, const sp_digit* a /*, const sp_digit* m*/)
310{ 607{
311 sp_256_add_10(r, a, a); 608// const sp_digit* m = p256_mod;
312 sp_256_norm_10(r); 609
313 if ((r[9] >> 22) > 0) 610 int carry = sp_256_add_8(r, a, a);
314 sp_256_sub_10(r, r, m); 611 sp_256_norm_8(r);
315 sp_256_norm_10(r); 612 if (carry)
613 sp_256_sub_8_p256_mod(r);
614 sp_256_norm_8(r);
316} 615}
317 616
318/* Triple a Montgomery form number (r = a + a + a % m) */ 617/* Triple a Montgomery form number (r = a + a + a % m) */
319static void sp_256_mont_tpl_10(sp_digit* r, const sp_digit* a, const sp_digit* m) 618static void sp_256_mont_tpl_8(sp_digit* r, const sp_digit* a /*, const sp_digit* m*/)
320{ 619{
321 sp_256_add_10(r, a, a); 620// const sp_digit* m = p256_mod;
322 sp_256_norm_10(r); 621
323 if ((r[9] >> 22) > 0) 622 int carry = sp_256_add_8(r, a, a);
324 sp_256_sub_10(r, r, m); 623 sp_256_norm_8(r);
325 sp_256_norm_10(r); 624 if (carry) {
326 sp_256_add_10(r, r, a); 625 sp_256_sub_8_p256_mod(r);
327 sp_256_norm_10(r); 626 sp_256_norm_8(r);
328 if ((r[9] >> 22) > 0) 627 }
329 sp_256_sub_10(r, r, m); 628 carry = sp_256_add_8(r, r, a);
330 sp_256_norm_10(r); 629 sp_256_norm_8(r);
630 if (carry) {
631 sp_256_sub_8_p256_mod(r);
632 sp_256_norm_8(r);
633 }
331} 634}
332 635
333/* Shift the result in the high 256 bits down to the bottom. */ 636/* Shift the result in the high 256 bits down to the bottom. */
334static void sp_256_mont_shift_10(sp_digit* r, const sp_digit* a) 637static void sp_256_mont_shift_8(sp_digit* r, const sp_digit* a)
335{ 638{
336 int i; 639 int i;
337 sp_digit n, s; 640
338 641 for (i = 0; i < 8; i++) {
339 s = a[10]; 642 r[i] = a[i+8];
340 n = a[9] >> 22; 643 r[i+8] = 0;
341 for (i = 0; i < 9; i++) {
342 n += (s & 0x3ffffff) << 4;
343 r[i] = n & 0x3ffffff;
344 n >>= 26;
345 s = a[11 + i] + (s >> 26);
346 } 644 }
347 n += s << 4; 645}
348 r[9] = n; 646
349 memset(&r[10], 0, sizeof(*r) * 10); 647/* Mul a by scalar b and add into r. (r += a * b) */
648static int sp_256_mul_add_8(sp_digit* r /*, const sp_digit* a, sp_digit b*/)
649{
650// const sp_digit* a = p256_mod;
651//a[7..0] = ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff
652 sp_digit b = r[0];
653
654 uint64_t t;
655
656// t = 0;
657// for (i = 0; i < 8; i++) {
658// uint32_t t_hi;
659// uint64_t m = ((uint64_t)b * a[i]) + r[i];
660// t += m;
661// t_hi = (t < m);
662// r[i] = (sp_digit)t;
663// t = (t >> 32) | ((uint64_t)t_hi << 32);
664// }
665// r[8] += (sp_digit)t;
666
667 // Unroll, then optimize the above loop:
668 //uint32_t t_hi;
669 uint64_t m;
670 uint32_t t32;
671
672 //m = ((uint64_t)b * a[0]) + r[0];
673 // Since b is r[0] and a[0] is ffffffff, the above optimizes to:
674 // m = r[0] * ffffffff + r[0] = (r[0] * 100000000 - r[0]) + r[0] = r[0] << 32;
675 //t += m;
676 // t = r[0] << 32 = b << 32;
677 //t_hi = (t < m);
678 // t_hi = 0;
679 //r[0] = (sp_digit)t;
680 r[0] = 0;
681 //t = (t >> 32) | ((uint64_t)t_hi << 32);
682 // t = b;
683
684 //m = ((uint64_t)b * a[1]) + r[1];
685 // Since a[1] is ffffffff, the above optimizes to:
686 // m = b * ffffffff + r[1] = (b * 100000000 - b) + r[1] = (b << 32) - b + r[1];
687 //t += m;
688 // t = b + (b << 32) - b + r[1] = (b << 32) + r[1];
689 //t_hi = (t < m);
690 // t_hi = 0;
691 //r[1] = (sp_digit)t;
692 // r[1] = r[1];
693 //t = (t >> 32) | ((uint64_t)t_hi << 32);
694 // t = b;
695
696 //m = ((uint64_t)b * a[2]) + r[2];
697 // Since a[2] is ffffffff, the above optimizes to:
698 // m = b * ffffffff + r[2] = (b * 100000000 - b) + r[2] = (b << 32) - b + r[2];
699 //t += m;
700 // t = b + (b << 32) - b + r[2] = (b << 32) + r[2]
701 //t_hi = (t < m);
702 // t_hi = 0;
703 //r[2] = (sp_digit)t;
704 // r[2] = r[2];
705 //t = (t >> 32) | ((uint64_t)t_hi << 32);
706 // t = b;
707
708 //m = ((uint64_t)b * a[3]) + r[3];
709 // Since a[3] is 00000000, the above optimizes to:
710 // m = b * 0 + r[3] = r[3];
711 //t += m;
712 // t = b + r[3];
713 //t_hi = (t < m);
714 // t_hi = 0;
715 //r[3] = (sp_digit)t;
716 r[3] = r[3] + b;
717 //t = (t >> 32) | ((uint64_t)t_hi << 32);
718 t32 = (r[3] < b); // 0 or 1
719
720 //m = ((uint64_t)b * a[4]) + r[4];
721 // Since a[4] is 00000000, the above optimizes to:
722 // m = b * 0 + r[4] = r[4];
723 //t += m;
724 // t = t32 + r[4];
725 //t_hi = (t < m);
726 // t_hi = 0;
727 //r[4] = (sp_digit)t;
728 //t = (t >> 32) | ((uint64_t)t_hi << 32);
729 if (t32 != 0) {
730 r[4]++;
731 t32 = (r[4] == 0); // 0 or 1
732
733 //m = ((uint64_t)b * a[5]) + r[5];
734 // Since a[5] is 00000000, the above optimizes to:
735 // m = b * 0 + r[5] = r[5];
736 //t += m;
737 // t = t32 + r[5]; (t32 is 0 or 1)
738 //t_hi = (t < m);
739 // t_hi = 0;
740 //r[5] = (sp_digit)t;
741 //t = (t >> 32) | ((uint64_t)t_hi << 32);
742 if (t32 != 0) {
743 r[5]++;
744 t32 = (r[5] == 0); // 0 or 1
745 }
746 }
747
748 //m = ((uint64_t)b * a[6]) + r[6];
749 // Since a[6] is 00000001, the above optimizes to:
750 // m = (uint64_t)b + r[6]; // 33 bits at most
751 //t += m;
752 t = t32 + (uint64_t)b + r[6];
753 //t_hi = (t < m);
754 // t_hi = 0;
755 r[6] = (sp_digit)t;
756 //t = (t >> 32) | ((uint64_t)t_hi << 32);
757 t = (t >> 32);
758
759 //m = ((uint64_t)b * a[7]) + r[7];
760 // Since a[7] is ffffffff, the above optimizes to:
761 // m = b * ffffffff + r[7] = (b * 100000000 - b) + r[7]
762 m = ((uint64_t)b << 32) - b + r[7];
763 t += m;
764 //t_hi = (t < m);
765 // t_hi in fact is always 0 here (256bit * 32bit can't have more than 32 bits of overflow)
766 r[7] = (sp_digit)t;
767 //t = (t >> 32) | ((uint64_t)t_hi << 32);
768 t = (t >> 32);
769
770 r[8] += (sp_digit)t;
771 return (r[8] < (sp_digit)t); /* 1 if addition overflowed */
350} 772}
351 773
352/* Reduce the number back to 256 bits using Montgomery reduction. 774/* Reduce the number back to 256 bits using Montgomery reduction.
@@ -355,39 +777,159 @@ static void sp_256_mont_shift_10(sp_digit* r, const sp_digit* a)
355 * m The single precision number representing the modulus. 777 * m The single precision number representing the modulus.
356 * mp The digit representing the negative inverse of m mod 2^n. 778 * mp The digit representing the negative inverse of m mod 2^n.
357 */ 779 */
358static void sp_256_mont_reduce_10(sp_digit* a, const sp_digit* m, sp_digit mp) 780static void sp_256_mont_reduce_8(sp_digit* a/*, const sp_digit* m, sp_digit mp*/)
359{ 781{
782// const sp_digit* m = p256_mod;
783 sp_digit mp = p256_mp_mod;
784
360 int i; 785 int i;
361 sp_digit mu; 786// sp_digit mu;
362 787
363 if (mp != 1) { 788 if (mp != 1) {
364 for (i = 0; i < 9; i++) { 789 sp_digit word16th = 0;
365 mu = (a[i] * mp) & 0x3ffffff; 790 for (i = 0; i < 8; i++) {
366 sp_256_mul_add_10(a+i, m, mu); 791// mu = (sp_digit)(a[i] * mp);
367 a[i+1] += a[i] >> 26; 792 if (sp_256_mul_add_8(a+i /*, m, mu*/)) {
793 int j = i + 8;
794 inc_next_word0:
795 if (++j > 15) { /* a[16] array has no more words? */
796 word16th++;
797 continue;
798 }
799 if (++a[j] == 0) /* did this overflow too? */
800 goto inc_next_word0;
801 }
368 } 802 }
369 mu = (a[i] * mp) & 0x3fffffl; 803 sp_256_mont_shift_8(a, a);
370 sp_256_mul_add_10(a+i, m, mu); 804 if (word16th != 0)
371 a[i+1] += a[i] >> 26; 805 sp_256_sub_8_p256_mod(a);
372 a[i] &= 0x3ffffff; 806 sp_256_norm_8(a);
373 } 807 }
374 else { 808 else { /* Same code for explicit mp == 1 (which is always the case for P256) */
375 for (i = 0; i < 9; i++) { 809 sp_digit word16th = 0;
376 mu = a[i] & 0x3ffffff; 810 for (i = 0; i < 8; i++) {
377 sp_256_mul_add_10(a+i, p256_mod, mu); 811 /*mu = a[i];*/
378 a[i+1] += a[i] >> 26; 812 if (sp_256_mul_add_8(a+i /*, m, mu*/)) {
813 int j = i + 8;
814 inc_next_word:
815 if (++j > 15) { /* a[16] array has no more words? */
816 word16th++;
817 continue;
818 }
819 if (++a[j] == 0) /* did this overflow too? */
820 goto inc_next_word;
821 }
379 } 822 }
380 mu = a[i] & 0x3fffffl; 823 sp_256_mont_shift_8(a, a);
381 sp_256_mul_add_10(a+i, p256_mod, mu); 824 if (word16th != 0)
382 a[i+1] += a[i] >> 26; 825 sp_256_sub_8_p256_mod(a);
383 a[i] &= 0x3ffffff; 826 sp_256_norm_8(a);
384 } 827 }
385
386 sp_256_mont_shift_10(a, a);
387 if ((a[9] >> 22) > 0)
388 sp_256_sub_10(a, a, m);
389 sp_256_norm_10(a);
390} 828}
829#if 0
830//TODO: arm32 asm (also adapt for x86?)
831static void sp_256_mont_reduce_8(sp_digit* a, sp_digit* m, sp_digit mp)
832{
833 sp_digit ca = 0;
834
835 asm volatile (
836 # i = 0
837 mov r12, #0
838 ldr r10, [%[a], #0]
839 ldr r14, [%[a], #4]
8401:
841 # mu = a[i] * mp
842 mul r8, %[mp], r10
843 # a[i+0] += m[0] * mu
844 ldr r7, [%[m], #0]
845 ldr r9, [%[a], #0]
846 umull r6, r7, r8, r7
847 adds r10, r10, r6
848 adc r5, r7, #0
849 # a[i+1] += m[1] * mu
850 ldr r7, [%[m], #4]
851 ldr r9, [%[a], #4]
852 umull r6, r7, r8, r7
853 adds r10, r14, r6
854 adc r4, r7, #0
855 adds r10, r10, r5
856 adc r4, r4, #0
857 # a[i+2] += m[2] * mu
858 ldr r7, [%[m], #8]
859 ldr r14, [%[a], #8]
860 umull r6, r7, r8, r7
861 adds r14, r14, r6
862 adc r5, r7, #0
863 adds r14, r14, r4
864 adc r5, r5, #0
865 # a[i+3] += m[3] * mu
866 ldr r7, [%[m], #12]
867 ldr r9, [%[a], #12]
868 umull r6, r7, r8, r7
869 adds r9, r9, r6
870 adc r4, r7, #0
871 adds r9, r9, r5
872 str r9, [%[a], #12]
873 adc r4, r4, #0
874 # a[i+4] += m[4] * mu
875 ldr r7, [%[m], #16]
876 ldr r9, [%[a], #16]
877 umull r6, r7, r8, r7
878 adds r9, r9, r6
879 adc r5, r7, #0
880 adds r9, r9, r4
881 str r9, [%[a], #16]
882 adc r5, r5, #0
883 # a[i+5] += m[5] * mu
884 ldr r7, [%[m], #20]
885 ldr r9, [%[a], #20]
886 umull r6, r7, r8, r7
887 adds r9, r9, r6
888 adc r4, r7, #0
889 adds r9, r9, r5
890 str r9, [%[a], #20]
891 adc r4, r4, #0
892 # a[i+6] += m[6] * mu
893 ldr r7, [%[m], #24]
894 ldr r9, [%[a], #24]
895 umull r6, r7, r8, r7
896 adds r9, r9, r6
897 adc r5, r7, #0
898 adds r9, r9, r4
899 str r9, [%[a], #24]
900 adc r5, r5, #0
901 # a[i+7] += m[7] * mu
902 ldr r7, [%[m], #28]
903 ldr r9, [%[a], #28]
904 umull r6, r7, r8, r7
905 adds r5, r5, r6
906 adcs r7, r7, %[ca]
907 mov %[ca], #0
908 adc %[ca], %[ca], %[ca]
909 adds r9, r9, r5
910 str r9, [%[a], #28]
911 ldr r9, [%[a], #32]
912 adcs r9, r9, r7
913 str r9, [%[a], #32]
914 adc %[ca], %[ca], #0
915 # i += 1
916 add %[a], %[a], #4
917 add r12, r12, #4
918 cmp r12, #32
919 blt 1b
920
921 str r10, [%[a], #0]
922 str r14, [%[a], #4]
923 : [ca] "+r" (ca), [a] "+r" (a)
924 : [m] "r" (m), [mp] "r" (mp)
925 : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12", "r14"
926 );
927
928 memcpy(a, a + 8, 32);
929 if (ca)
930 a -= m;
931}
932#endif
391 933
392/* Multiply two Montogmery form numbers mod the modulus (prime). 934/* Multiply two Montogmery form numbers mod the modulus (prime).
393 * (r = a * b mod m) 935 * (r = a * b mod m)
@@ -398,11 +940,13 @@ static void sp_256_mont_reduce_10(sp_digit* a, const sp_digit* m, sp_digit mp)
398 * m Modulus (prime). 940 * m Modulus (prime).
399 * mp Montogmery mulitplier. 941 * mp Montogmery mulitplier.
400 */ 942 */
401static void sp_256_mont_mul_10(sp_digit* r, const sp_digit* a, const sp_digit* b, 943static void sp_256_mont_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b
402 const sp_digit* m, sp_digit mp) 944 /*, const sp_digit* m, sp_digit mp*/)
403{ 945{
404 sp_256_mul_10(r, a, b); 946 //const sp_digit* m = p256_mod;
405 sp_256_mont_reduce_10(r, m, mp); 947 //sp_digit mp = p256_mp_mod;
948 sp_256_mul_8(r, a, b);
949 sp_256_mont_reduce_8(r /*, m, mp*/);
406} 950}
407 951
408/* Square the Montgomery form number. (r = a * a mod m) 952/* Square the Montgomery form number. (r = a * a mod m)
@@ -412,11 +956,12 @@ static void sp_256_mont_mul_10(sp_digit* r, const sp_digit* a, const sp_digit* b
412 * m Modulus (prime). 956 * m Modulus (prime).
413 * mp Montogmery mulitplier. 957 * mp Montogmery mulitplier.
414 */ 958 */
415static void sp_256_mont_sqr_10(sp_digit* r, const sp_digit* a, const sp_digit* m, 959static void sp_256_mont_sqr_8(sp_digit* r, const sp_digit* a
416 sp_digit mp) 960 /*, const sp_digit* m, sp_digit mp*/)
417{ 961{
418 sp_256_sqr_10(r, a); 962 //const sp_digit* m = p256_mod;
419 sp_256_mont_reduce_10(r, m, mp); 963 //sp_digit mp = p256_mp_mod;
964 sp_256_mont_mul_8(r, a, a /*, m, mp*/);
420} 965}
421 966
422/* Invert the number, in Montgomery form, modulo the modulus (prime) of the 967/* Invert the number, in Montgomery form, modulo the modulus (prime) of the
@@ -437,19 +982,19 @@ static const uint32_t p256_mod_2[8] = {
437//543210987654321098765432109876543210987654321098765432109876543210...09876543210...09876543210 982//543210987654321098765432109876543210987654321098765432109876543210...09876543210...09876543210
438//111111111111111111111111111111110000000000000000000000000000000100...00000111111...11111111101 983//111111111111111111111111111111110000000000000000000000000000000100...00000111111...11111111101
439#endif 984#endif
440static void sp_256_mont_inv_10(sp_digit* r, sp_digit* a) 985static void sp_256_mont_inv_8(sp_digit* r, sp_digit* a)
441{ 986{
442 sp_digit t[2*10]; //can be just [10]? 987 sp_digit t[2*8]; //can be just [8]?
443 int i; 988 int i;
444 989
445 memcpy(t, a, sizeof(sp_digit) * 10); 990 memcpy(t, a, sizeof(sp_digit) * 8);
446 for (i = 254; i >= 0; i--) { 991 for (i = 254; i >= 0; i--) {
447 sp_256_mont_sqr_10(t, t, p256_mod, p256_mp_mod); 992 sp_256_mont_sqr_8(t, t /*, p256_mod, p256_mp_mod*/);
448 /*if (p256_mod_2[i / 32] & ((sp_digit)1 << (i % 32)))*/ 993 /*if (p256_mod_2[i / 32] & ((sp_digit)1 << (i % 32)))*/
449 if (i >= 224 || i == 192 || (i <= 95 && i != 1)) 994 if (i >= 224 || i == 192 || (i <= 95 && i != 1))
450 sp_256_mont_mul_10(t, t, a, p256_mod, p256_mp_mod); 995 sp_256_mont_mul_8(t, t, a /*, p256_mod, p256_mp_mod*/);
451 } 996 }
452 memcpy(r, t, sizeof(sp_digit) * 10); 997 memcpy(r, t, sizeof(sp_digit) * 8);
453} 998}
454 999
455/* Multiply a number by Montogmery normalizer mod modulus (prime). 1000/* Multiply a number by Montogmery normalizer mod modulus (prime).
@@ -457,93 +1002,29 @@ static void sp_256_mont_inv_10(sp_digit* r, sp_digit* a)
457 * r The resulting Montgomery form number. 1002 * r The resulting Montgomery form number.
458 * a The number to convert. 1003 * a The number to convert.
459 */ 1004 */
460static void sp_256_mod_mul_norm_10(sp_digit* r, const sp_digit* a) 1005static void sp_256_mod_mul_norm_8(sp_digit* r, const sp_digit* a)
461{ 1006{
462 int64_t t[8]; 1007 int64_t t[8];
463 int64_t o; 1008 int32_t o;
464 uint32_t a32;
465 1009
1010#define A(n) ((uint64_t)a[n])
466 /* 1 1 0 -1 -1 -1 -1 0 */ 1011 /* 1 1 0 -1 -1 -1 -1 0 */
1012 t[0] = 0 + A(0) + A(1) - A(3) - A(4) - A(5) - A(6);
467 /* 0 1 1 0 -1 -1 -1 -1 */ 1013 /* 0 1 1 0 -1 -1 -1 -1 */
1014 t[1] = 0 + A(1) + A(2) - A(4) - A(5) - A(6) - A(7);
468 /* 0 0 1 1 0 -1 -1 -1 */ 1015 /* 0 0 1 1 0 -1 -1 -1 */
1016 t[2] = 0 + A(2) + A(3) - A(5) - A(6) - A(7);
469 /* -1 -1 0 2 2 1 0 -1 */ 1017 /* -1 -1 0 2 2 1 0 -1 */
1018 t[3] = 0 - A(0) - A(1) + 2 * A(3) + 2 * A(4) + A(5) - A(7);
470 /* 0 -1 -1 0 2 2 1 0 */ 1019 /* 0 -1 -1 0 2 2 1 0 */
1020 t[4] = 0 - A(1) - A(2) + 2 * A(4) + 2 * A(5) + A(6);
471 /* 0 0 -1 -1 0 2 2 1 */ 1021 /* 0 0 -1 -1 0 2 2 1 */
1022 t[5] = 0 - A(2) - A(3) + 2 * A(5) + 2 * A(6) + A(7);
472 /* -1 -1 0 0 0 1 3 2 */ 1023 /* -1 -1 0 0 0 1 3 2 */
1024 t[6] = 0 - A(0) - A(1) + A(5) + 3 * A(6) + 2 * A(7);
473 /* 1 0 -1 -1 -1 -1 0 3 */ 1025 /* 1 0 -1 -1 -1 -1 0 3 */
474 // t[] should be calculated from "a" (converted from 26-bit to 32-bit vector a32[8]) 1026 t[7] = 0 + A(0) - A(2) - A(3) - A(4) - A(5) + 3 * A(7);
475 // according to the above matrix: 1027#undef A
476 //t[0] = 0 + a32[0] + a32[1] - a32[3] - a32[4] - a32[5] - a32[6] ;
477 //t[1] = 0 + a32[1] + a32[2] - a32[4] - a32[5] - a32[6] - a32[7] ;
478 //t[2] = 0 + a32[2] + a32[3] - a32[5] - a32[6] - a32[7] ;
479 //t[3] = 0 - a32[0] - a32[1] + 2*a32[3] + 2*a32[4] + a32[5] - a32[7] ;
480 //t[4] = 0 - a32[1] - a32[2] + 2*a32[4] + 2*a32[5] + a32[6] ;
481 //t[5] = 0 - a32[2] - a32[3] + 2*a32[5] + 2*a32[6] + a32[7] ;
482 //t[6] = 0 - a32[0] - a32[1] + a32[5] + 3*a32[6] + 2*a32[7];
483 //t[7] = 0 + a32[0] - a32[2] - a32[3] - a32[4] - a32[5] + 3*a32[7];
484 // We can do it "piecemeal" after each a32[i] is known, no need to store entire a32[8] vector:
485
486#define A32 (int64_t)a32
487 a32 = a[0] | (a[1] << 26);
488 t[0] = 0 + A32;
489 t[3] = 0 - A32;
490 t[6] = 0 - A32;
491 t[7] = 0 + A32;
492
493 a32 = (a[1] >> 6) | (a[2] << 20);
494 t[0] += A32 ;
495 t[1] = 0 + A32;
496 t[3] -= A32 ;
497 t[4] = 0 - A32;
498 t[6] -= A32 ;
499
500 a32 = (a[2] >> 12) | (a[3] << 14);
501 t[1] += A32 ;
502 t[2] = 0 + A32;
503 t[4] -= A32 ;
504 t[5] = 0 - A32;
505 t[7] -= A32 ;
506
507 a32 = (a[3] >> 18) | (a[4] << 8);
508 t[0] -= A32 ;
509 t[2] += A32 ;
510 t[3] += 2*A32;
511 t[5] -= A32 ;
512 t[7] -= A32 ;
513
514 a32 = (a[4] >> 24) | (a[5] << 2) | (a[6] << 28);
515 t[0] -= A32 ;
516 t[1] -= A32 ;
517 t[3] += 2*A32;
518 t[4] += 2*A32;
519 t[7] -= A32 ;
520
521 a32 = (a[6] >> 4) | (a[7] << 22);
522 t[0] -= A32 ;
523 t[1] -= A32 ;
524 t[2] -= A32 ;
525 t[3] += A32 ;
526 t[4] += 2*A32;
527 t[5] += 2*A32;
528 t[6] += A32 ;
529 t[7] -= A32 ;
530
531 a32 = (a[7] >> 10) | (a[8] << 16);
532 t[0] -= A32 ;
533 t[1] -= A32 ;
534 t[2] -= A32 ;
535 t[4] += A32 ;
536 t[5] += 2*A32;
537 t[6] += 3*A32;
538
539 a32 = (a[8] >> 16) | (a[9] << 10);
540 t[1] -= A32 ;
541 t[2] -= A32 ;
542 t[3] -= A32 ;
543 t[5] += A32 ;
544 t[6] += 2*A32;
545 t[7] += 3*A32;
546#undef A32
547 1028
548 t[1] += t[0] >> 32; t[0] &= 0xffffffff; 1029 t[1] += t[0] >> 32; t[0] &= 0xffffffff;
549 t[2] += t[1] >> 32; t[1] &= 0xffffffff; 1030 t[2] += t[1] >> 32; t[1] &= 0xffffffff;
@@ -552,29 +1033,27 @@ static void sp_256_mod_mul_norm_10(sp_digit* r, const sp_digit* a)
552 t[5] += t[4] >> 32; t[4] &= 0xffffffff; 1033 t[5] += t[4] >> 32; t[4] &= 0xffffffff;
553 t[6] += t[5] >> 32; t[5] &= 0xffffffff; 1034 t[6] += t[5] >> 32; t[5] &= 0xffffffff;
554 t[7] += t[6] >> 32; t[6] &= 0xffffffff; 1035 t[7] += t[6] >> 32; t[6] &= 0xffffffff;
555 o = t[7] >> 32; t[7] &= 0xffffffff; 1036 o = t[7] >> 32; //t[7] &= 0xffffffff;
556 t[0] += o; 1037 t[0] += o;
557 t[3] -= o; 1038 t[3] -= o;
558 t[6] -= o; 1039 t[6] -= o;
559 t[7] += o; 1040 t[7] += o;
560 t[1] += t[0] >> 32; //t[0] &= 0xffffffff; 1041 r[0] = (sp_digit)t[0];
561 t[2] += t[1] >> 32; //t[1] &= 0xffffffff; 1042 t[1] += t[0] >> 32;
562 t[3] += t[2] >> 32; //t[2] &= 0xffffffff; 1043 r[1] = (sp_digit)t[1];
563 t[4] += t[3] >> 32; //t[3] &= 0xffffffff; 1044 t[2] += t[1] >> 32;
564 t[5] += t[4] >> 32; //t[4] &= 0xffffffff; 1045 r[2] = (sp_digit)t[2];
565 t[6] += t[5] >> 32; //t[5] &= 0xffffffff; 1046 t[3] += t[2] >> 32;
566 t[7] += t[6] >> 32; //t[6] &= 0xffffffff; - (uint32_t)t[i] casts below accomplish masking 1047 r[3] = (sp_digit)t[3];
567 1048 t[4] += t[3] >> 32;
568 r[0] = 0x3ffffff & ((sp_digit)((uint32_t)t[0])); 1049 r[4] = (sp_digit)t[4];
569 r[1] = 0x3ffffff & ((sp_digit)((uint32_t)t[0] >> 26) | ((sp_digit)t[1] << 6)); 1050 t[5] += t[4] >> 32;
570 r[2] = 0x3ffffff & ((sp_digit)((uint32_t)t[1] >> 20) | ((sp_digit)t[2] << 12)); 1051 r[5] = (sp_digit)t[5];
571 r[3] = 0x3ffffff & ((sp_digit)((uint32_t)t[2] >> 14) | ((sp_digit)t[3] << 18)); 1052 t[6] += t[5] >> 32;
572 r[4] = 0x3ffffff & ((sp_digit)((uint32_t)t[3] >> 8) | ((sp_digit)t[4] << 24)); 1053 r[6] = (sp_digit)t[6];
573 r[5] = 0x3ffffff & ((sp_digit)((uint32_t)t[4] >> 2)); 1054// t[7] += t[6] >> 32;
574 r[6] = 0x3ffffff & ((sp_digit)((uint32_t)t[4] >> 28) | ((sp_digit)t[5] << 4)); 1055// r[7] = (sp_digit)t[7];
575 r[7] = 0x3ffffff & ((sp_digit)((uint32_t)t[5] >> 22) | ((sp_digit)t[6] << 10)); 1056 r[7] = (sp_digit)t[7] + (sp_digit)(t[6] >> 32);
576 r[8] = 0x3ffffff & ((sp_digit)((uint32_t)t[6] >> 16) | ((sp_digit)t[7] << 16));
577 r[9] = ((sp_digit)((uint32_t)t[7] >> 10));
578} 1057}
579 1058
580/* Map the Montgomery form projective co-ordinate point to an affine point. 1059/* Map the Montgomery form projective co-ordinate point to an affine point.
@@ -582,33 +1061,33 @@ static void sp_256_mod_mul_norm_10(sp_digit* r, const sp_digit* a)
582 * r Resulting affine co-ordinate point. 1061 * r Resulting affine co-ordinate point.
583 * p Montgomery form projective co-ordinate point. 1062 * p Montgomery form projective co-ordinate point.
584 */ 1063 */
585static void sp_256_map_10(sp_point* r, sp_point* p) 1064static void sp_256_map_8(sp_point* r, sp_point* p)
586{ 1065{
587 sp_digit t1[2*10]; 1066 sp_digit t1[2*8];
588 sp_digit t2[2*10]; 1067 sp_digit t2[2*8];
589 1068
590 sp_256_mont_inv_10(t1, p->z); 1069 sp_256_mont_inv_8(t1, p->z);
591 1070
592 sp_256_mont_sqr_10(t2, t1, p256_mod, p256_mp_mod); 1071 sp_256_mont_sqr_8(t2, t1 /*, p256_mod, p256_mp_mod*/);
593 sp_256_mont_mul_10(t1, t2, t1, p256_mod, p256_mp_mod); 1072 sp_256_mont_mul_8(t1, t2, t1 /*, p256_mod, p256_mp_mod*/);
594 1073
595 /* x /= z^2 */ 1074 /* x /= z^2 */
596 sp_256_mont_mul_10(r->x, p->x, t2, p256_mod, p256_mp_mod); 1075 sp_256_mont_mul_8(r->x, p->x, t2 /*, p256_mod, p256_mp_mod*/);
597 memset(r->x + 10, 0, sizeof(r->x) / 2); 1076 memset(r->x + 8, 0, sizeof(r->x) / 2);
598 sp_256_mont_reduce_10(r->x, p256_mod, p256_mp_mod); 1077 sp_256_mont_reduce_8(r->x /*, p256_mod, p256_mp_mod*/);
599 /* Reduce x to less than modulus */ 1078 /* Reduce x to less than modulus */
600 if (sp_256_cmp_10(r->x, p256_mod) >= 0) 1079 if (sp_256_cmp_8(r->x, p256_mod) >= 0)
601 sp_256_sub_10(r->x, r->x, p256_mod); 1080 sp_256_sub_8_p256_mod(r->x);
602 sp_256_norm_10(r->x); 1081 sp_256_norm_8(r->x);
603 1082
604 /* y /= z^3 */ 1083 /* y /= z^3 */
605 sp_256_mont_mul_10(r->y, p->y, t1, p256_mod, p256_mp_mod); 1084 sp_256_mont_mul_8(r->y, p->y, t1 /*, p256_mod, p256_mp_mod*/);
606 memset(r->y + 10, 0, sizeof(r->y) / 2); 1085 memset(r->y + 8, 0, sizeof(r->y) / 2);
607 sp_256_mont_reduce_10(r->y, p256_mod, p256_mp_mod); 1086 sp_256_mont_reduce_8(r->y /*, p256_mod, p256_mp_mod*/);
608 /* Reduce y to less than modulus */ 1087 /* Reduce y to less than modulus */
609 if (sp_256_cmp_10(r->y, p256_mod) >= 0) 1088 if (sp_256_cmp_8(r->y, p256_mod) >= 0)
610 sp_256_sub_10(r->y, r->y, p256_mod); 1089 sp_256_sub_8_p256_mod(r->y);
611 sp_256_norm_10(r->y); 1090 sp_256_norm_8(r->y);
612 1091
613 memset(r->z, 0, sizeof(r->z)); 1092 memset(r->z, 0, sizeof(r->z));
614 r->z[0] = 1; 1093 r->z[0] = 1;
@@ -619,56 +1098,62 @@ static void sp_256_map_10(sp_point* r, sp_point* p)
619 * r Result of doubling point. 1098 * r Result of doubling point.
620 * p Point to double. 1099 * p Point to double.
621 */ 1100 */
622static void sp_256_proj_point_dbl_10(sp_point* r, sp_point* p) 1101static void sp_256_proj_point_dbl_8(sp_point* r, sp_point* p)
623{ 1102{
624 sp_point tp; 1103 sp_digit t1[2*8];
625 sp_digit t1[2*10]; 1104 sp_digit t2[2*8];
626 sp_digit t2[2*10];
627 1105
628 /* Put point to double into result */ 1106 /* Put point to double into result */
629 if (r != p) 1107 if (r != p)
630 *r = *p; /* struct copy */ 1108 *r = *p; /* struct copy */
631 1109
632 if (r->infinity) { 1110 if (r->infinity)
633 /* If infinity, don't double (work on dummy value) */ 1111 return;
634 r = &tp; 1112
1113 if (SP_DEBUG) {
1114 /* unused part of t2, may result in spurios
1115 * differences in debug output. Clear it.
1116 */
1117 memset(t2, 0, sizeof(t2));
635 } 1118 }
1119
636 /* T1 = Z * Z */ 1120 /* T1 = Z * Z */
637 sp_256_mont_sqr_10(t1, r->z, p256_mod, p256_mp_mod); 1121 sp_256_mont_sqr_8(t1, r->z /*, p256_mod, p256_mp_mod*/);
638 /* Z = Y * Z */ 1122 /* Z = Y * Z */
639 sp_256_mont_mul_10(r->z, r->y, r->z, p256_mod, p256_mp_mod); 1123 sp_256_mont_mul_8(r->z, r->y, r->z /*, p256_mod, p256_mp_mod*/);
640 /* Z = 2Z */ 1124 /* Z = 2Z */
641 sp_256_mont_dbl_10(r->z, r->z, p256_mod); 1125 sp_256_mont_dbl_8(r->z, r->z /*, p256_mod*/);
642 /* T2 = X - T1 */ 1126 /* T2 = X - T1 */
643 sp_256_mont_sub_10(t2, r->x, t1, p256_mod); 1127 sp_256_mont_sub_8(t2, r->x, t1 /*, p256_mod*/);
644 /* T1 = X + T1 */ 1128 /* T1 = X + T1 */
645 sp_256_mont_add_10(t1, r->x, t1, p256_mod); 1129 sp_256_mont_add_8(t1, r->x, t1 /*, p256_mod*/);
646 /* T2 = T1 * T2 */ 1130 /* T2 = T1 * T2 */
647 sp_256_mont_mul_10(t2, t1, t2, p256_mod, p256_mp_mod); 1131 sp_256_mont_mul_8(t2, t1, t2 /*, p256_mod, p256_mp_mod*/);
648 /* T1 = 3T2 */ 1132 /* T1 = 3T2 */
649 sp_256_mont_tpl_10(t1, t2, p256_mod); 1133 sp_256_mont_tpl_8(t1, t2 /*, p256_mod*/);
650 /* Y = 2Y */ 1134 /* Y = 2Y */
651 sp_256_mont_dbl_10(r->y, r->y, p256_mod); 1135 sp_256_mont_dbl_8(r->y, r->y /*, p256_mod*/);
652 /* Y = Y * Y */ 1136 /* Y = Y * Y */
653 sp_256_mont_sqr_10(r->y, r->y, p256_mod, p256_mp_mod); 1137 sp_256_mont_sqr_8(r->y, r->y /*, p256_mod, p256_mp_mod*/);
654 /* T2 = Y * Y */ 1138 /* T2 = Y * Y */
655 sp_256_mont_sqr_10(t2, r->y, p256_mod, p256_mp_mod); 1139 sp_256_mont_sqr_8(t2, r->y /*, p256_mod, p256_mp_mod*/);
656 /* T2 = T2/2 */ 1140 /* T2 = T2/2 */
657 sp_256_div2_10(t2, t2, p256_mod); 1141 sp_256_div2_8(t2, t2, p256_mod);
658 /* Y = Y * X */ 1142 /* Y = Y * X */
659 sp_256_mont_mul_10(r->y, r->y, r->x, p256_mod, p256_mp_mod); 1143 sp_256_mont_mul_8(r->y, r->y, r->x /*, p256_mod, p256_mp_mod*/);
660 /* X = T1 * T1 */ 1144 /* X = T1 * T1 */
661 sp_256_mont_mul_10(r->x, t1, t1, p256_mod, p256_mp_mod); 1145 sp_256_mont_mul_8(r->x, t1, t1 /*, p256_mod, p256_mp_mod*/);
662 /* X = X - Y */ 1146 /* X = X - Y */
663 sp_256_mont_sub_10(r->x, r->x, r->y, p256_mod); 1147 sp_256_mont_sub_8(r->x, r->x, r->y /*, p256_mod*/);
664 /* X = X - Y */ 1148 /* X = X - Y */
665 sp_256_mont_sub_10(r->x, r->x, r->y, p256_mod); 1149 sp_256_mont_sub_8(r->x, r->x, r->y /*, p256_mod*/);
666 /* Y = Y - X */ 1150 /* Y = Y - X */
667 sp_256_mont_sub_10(r->y, r->y, r->x, p256_mod); 1151 sp_256_mont_sub_8(r->y, r->y, r->x /*, p256_mod*/);
668 /* Y = Y * T1 */ 1152 /* Y = Y * T1 */
669 sp_256_mont_mul_10(r->y, r->y, t1, p256_mod, p256_mp_mod); 1153 sp_256_mont_mul_8(r->y, r->y, t1 /*, p256_mod, p256_mp_mod*/);
670 /* Y = Y - T2 */ 1154 /* Y = Y - T2 */
671 sp_256_mont_sub_10(r->y, r->y, t2, p256_mod); 1155 sp_256_mont_sub_8(r->y, r->y, t2 /*, p256_mod*/);
1156 dump_512("y2 %s\n", r->y);
672} 1157}
673 1158
674/* Add two Montgomery form projective points. 1159/* Add two Montgomery form projective points.
@@ -677,13 +1162,13 @@ static void sp_256_proj_point_dbl_10(sp_point* r, sp_point* p)
677 * p Frist point to add. 1162 * p Frist point to add.
678 * q Second point to add. 1163 * q Second point to add.
679 */ 1164 */
680static void sp_256_proj_point_add_10(sp_point* r, sp_point* p, sp_point* q) 1165static NOINLINE void sp_256_proj_point_add_8(sp_point* r, sp_point* p, sp_point* q)
681{ 1166{
682 sp_digit t1[2*10]; 1167 sp_digit t1[2*8];
683 sp_digit t2[2*10]; 1168 sp_digit t2[2*8];
684 sp_digit t3[2*10]; 1169 sp_digit t3[2*8];
685 sp_digit t4[2*10]; 1170 sp_digit t4[2*8];
686 sp_digit t5[2*10]; 1171 sp_digit t5[2*8];
687 1172
688 /* Ensure only the first point is the same as the result. */ 1173 /* Ensure only the first point is the same as the result. */
689 if (q == r) { 1174 if (q == r) {
@@ -693,13 +1178,13 @@ static void sp_256_proj_point_add_10(sp_point* r, sp_point* p, sp_point* q)
693 } 1178 }
694 1179
695 /* Check double */ 1180 /* Check double */
696 sp_256_sub_10(t1, p256_mod, q->y); 1181 sp_256_sub_8(t1, p256_mod, q->y);
697 sp_256_norm_10(t1); 1182 sp_256_norm_8(t1);
698 if (sp_256_cmp_equal_10(p->x, q->x) 1183 if (sp_256_cmp_equal_8(p->x, q->x)
699 && sp_256_cmp_equal_10(p->z, q->z) 1184 && sp_256_cmp_equal_8(p->z, q->z)
700 && (sp_256_cmp_equal_10(p->y, q->y) || sp_256_cmp_equal_10(p->y, t1)) 1185 && (sp_256_cmp_equal_8(p->y, q->y) || sp_256_cmp_equal_8(p->y, t1))
701 ) { 1186 ) {
702 sp_256_proj_point_dbl_10(r, p); 1187 sp_256_proj_point_dbl_8(r, p);
703 } 1188 }
704 else { 1189 else {
705 sp_point tp; 1190 sp_point tp;
@@ -714,37 +1199,37 @@ static void sp_256_proj_point_add_10(sp_point* r, sp_point* p, sp_point* q)
714 *r = p->infinity ? *q : *p; /* struct copy */ 1199 *r = p->infinity ? *q : *p; /* struct copy */
715 1200
716 /* U1 = X1*Z2^2 */ 1201 /* U1 = X1*Z2^2 */
717 sp_256_mont_sqr_10(t1, q->z, p256_mod, p256_mp_mod); 1202 sp_256_mont_sqr_8(t1, q->z /*, p256_mod, p256_mp_mod*/);
718 sp_256_mont_mul_10(t3, t1, q->z, p256_mod, p256_mp_mod); 1203 sp_256_mont_mul_8(t3, t1, q->z /*, p256_mod, p256_mp_mod*/);
719 sp_256_mont_mul_10(t1, t1, v->x, p256_mod, p256_mp_mod); 1204 sp_256_mont_mul_8(t1, t1, v->x /*, p256_mod, p256_mp_mod*/);
720 /* U2 = X2*Z1^2 */ 1205 /* U2 = X2*Z1^2 */
721 sp_256_mont_sqr_10(t2, v->z, p256_mod, p256_mp_mod); 1206 sp_256_mont_sqr_8(t2, v->z /*, p256_mod, p256_mp_mod*/);
722 sp_256_mont_mul_10(t4, t2, v->z, p256_mod, p256_mp_mod); 1207 sp_256_mont_mul_8(t4, t2, v->z /*, p256_mod, p256_mp_mod*/);
723 sp_256_mont_mul_10(t2, t2, q->x, p256_mod, p256_mp_mod); 1208 sp_256_mont_mul_8(t2, t2, q->x /*, p256_mod, p256_mp_mod*/);
724 /* S1 = Y1*Z2^3 */ 1209 /* S1 = Y1*Z2^3 */
725 sp_256_mont_mul_10(t3, t3, v->y, p256_mod, p256_mp_mod); 1210 sp_256_mont_mul_8(t3, t3, v->y /*, p256_mod, p256_mp_mod*/);
726 /* S2 = Y2*Z1^3 */ 1211 /* S2 = Y2*Z1^3 */
727 sp_256_mont_mul_10(t4, t4, q->y, p256_mod, p256_mp_mod); 1212 sp_256_mont_mul_8(t4, t4, q->y /*, p256_mod, p256_mp_mod*/);
728 /* H = U2 - U1 */ 1213 /* H = U2 - U1 */
729 sp_256_mont_sub_10(t2, t2, t1, p256_mod); 1214 sp_256_mont_sub_8(t2, t2, t1 /*, p256_mod*/);
730 /* R = S2 - S1 */ 1215 /* R = S2 - S1 */
731 sp_256_mont_sub_10(t4, t4, t3, p256_mod); 1216 sp_256_mont_sub_8(t4, t4, t3 /*, p256_mod*/);
732 /* Z3 = H*Z1*Z2 */ 1217 /* Z3 = H*Z1*Z2 */
733 sp_256_mont_mul_10(v->z, v->z, q->z, p256_mod, p256_mp_mod); 1218 sp_256_mont_mul_8(v->z, v->z, q->z /*, p256_mod, p256_mp_mod*/);
734 sp_256_mont_mul_10(v->z, v->z, t2, p256_mod, p256_mp_mod); 1219 sp_256_mont_mul_8(v->z, v->z, t2 /*, p256_mod, p256_mp_mod*/);
735 /* X3 = R^2 - H^3 - 2*U1*H^2 */ 1220 /* X3 = R^2 - H^3 - 2*U1*H^2 */
736 sp_256_mont_sqr_10(v->x, t4, p256_mod, p256_mp_mod); 1221 sp_256_mont_sqr_8(v->x, t4 /*, p256_mod, p256_mp_mod*/);
737 sp_256_mont_sqr_10(t5, t2, p256_mod, p256_mp_mod); 1222 sp_256_mont_sqr_8(t5, t2 /*, p256_mod, p256_mp_mod*/);
738 sp_256_mont_mul_10(v->y, t1, t5, p256_mod, p256_mp_mod); 1223 sp_256_mont_mul_8(v->y, t1, t5 /*, p256_mod, p256_mp_mod*/);
739 sp_256_mont_mul_10(t5, t5, t2, p256_mod, p256_mp_mod); 1224 sp_256_mont_mul_8(t5, t5, t2 /*, p256_mod, p256_mp_mod*/);
740 sp_256_mont_sub_10(v->x, v->x, t5, p256_mod); 1225 sp_256_mont_sub_8(v->x, v->x, t5 /*, p256_mod*/);
741 sp_256_mont_dbl_10(t1, v->y, p256_mod); 1226 sp_256_mont_dbl_8(t1, v->y /*, p256_mod*/);
742 sp_256_mont_sub_10(v->x, v->x, t1, p256_mod); 1227 sp_256_mont_sub_8(v->x, v->x, t1 /*, p256_mod*/);
743 /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ 1228 /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
744 sp_256_mont_sub_10(v->y, v->y, v->x, p256_mod); 1229 sp_256_mont_sub_8(v->y, v->y, v->x /*, p256_mod*/);
745 sp_256_mont_mul_10(v->y, v->y, t4, p256_mod, p256_mp_mod); 1230 sp_256_mont_mul_8(v->y, v->y, t4 /*, p256_mod, p256_mp_mod*/);
746 sp_256_mont_mul_10(t5, t5, t3, p256_mod, p256_mp_mod); 1231 sp_256_mont_mul_8(t5, t5, t3 /*, p256_mod, p256_mp_mod*/);
747 sp_256_mont_sub_10(v->y, v->y, t5, p256_mod); 1232 sp_256_mont_sub_8(v->y, v->y, t5 /*, p256_mod*/);
748 } 1233 }
749} 1234}
750 1235
@@ -756,12 +1241,11 @@ static void sp_256_proj_point_add_10(sp_point* r, sp_point* p, sp_point* q)
756 * k Scalar to multiply by. 1241 * k Scalar to multiply by.
757 * map Indicates whether to convert result to affine. 1242 * map Indicates whether to convert result to affine.
758 */ 1243 */
759static void sp_256_ecc_mulmod_10(sp_point* r, const sp_point* g, const sp_digit* k /*, int map*/) 1244static void sp_256_ecc_mulmod_8(sp_point* r, const sp_point* g, const sp_digit* k /*, int map*/)
760{ 1245{
761 enum { map = 1 }; /* we always convert result to affine coordinates */ 1246 enum { map = 1 }; /* we always convert result to affine coordinates */
762 sp_point t[3]; 1247 sp_point t[3];
763 sp_digit n; 1248 sp_digit n = n; /* for compiler */
764 int i;
765 int c, y; 1249 int c, y;
766 1250
767 memset(t, 0, sizeof(t)); 1251 memset(t, 0, sizeof(t));
@@ -769,33 +1253,44 @@ static void sp_256_ecc_mulmod_10(sp_point* r, const sp_point* g, const sp_digit*
769 /* t[0] = {0, 0, 1} * norm */ 1253 /* t[0] = {0, 0, 1} * norm */
770 t[0].infinity = 1; 1254 t[0].infinity = 1;
771 /* t[1] = {g->x, g->y, g->z} * norm */ 1255 /* t[1] = {g->x, g->y, g->z} * norm */
772 sp_256_mod_mul_norm_10(t[1].x, g->x); 1256 sp_256_mod_mul_norm_8(t[1].x, g->x);
773 sp_256_mod_mul_norm_10(t[1].y, g->y); 1257 sp_256_mod_mul_norm_8(t[1].y, g->y);
774 sp_256_mod_mul_norm_10(t[1].z, g->z); 1258 sp_256_mod_mul_norm_8(t[1].z, g->z);
775
776 i = 9;
777 c = 22;
778 n = k[i--] << (26 - c);
779 for (; ; c--) {
780 if (c == 0) {
781 if (i == -1)
782 break;
783 1259
784 n = k[i--]; 1260 /* For every bit, starting from most significant... */
785 c = 26; 1261 k += 7;
1262 c = 256;
1263 for (;;) {
1264 if ((c & 0x1f) == 0) {
1265 if (c == 0)
1266 break;
1267 n = *k--;
786 } 1268 }
787 1269
788 y = (n >> 25) & 1; 1270 y = (n >> 31);
789 n <<= 1; 1271 dbg("y:%d t[%d] = t[0]+t[1]\n", y, y^1);
790 1272 sp_256_proj_point_add_8(&t[y^1], &t[0], &t[1]);
791 sp_256_proj_point_add_10(&t[y^1], &t[0], &t[1]); 1273 dump_512("t[0].x %s\n", t[0].x);
1274 dump_512("t[0].y %s\n", t[0].y);
1275 dump_512("t[0].z %s\n", t[0].z);
1276 dump_512("t[1].x %s\n", t[1].x);
1277 dump_512("t[1].y %s\n", t[1].y);
1278 dump_512("t[1].z %s\n", t[1].z);
1279 dbg("t[2] = t[%d]\n", y);
792 memcpy(&t[2], &t[y], sizeof(sp_point)); 1280 memcpy(&t[2], &t[y], sizeof(sp_point));
793 sp_256_proj_point_dbl_10(&t[2], &t[2]); 1281 dbg("t[2] *= 2\n");
1282 sp_256_proj_point_dbl_8(&t[2], &t[2]);
1283 dump_512("t[2].x %s\n", t[2].x);
1284 dump_512("t[2].y %s\n", t[2].y);
1285 dump_512("t[2].z %s\n", t[2].z);
794 memcpy(&t[y], &t[2], sizeof(sp_point)); 1286 memcpy(&t[y], &t[2], sizeof(sp_point));
1287
1288 n <<= 1;
1289 c--;
795 } 1290 }
796 1291
797 if (map) 1292 if (map)
798 sp_256_map_10(r, &t[0]); 1293 sp_256_map_8(r, &t[0]);
799 else 1294 else
800 memcpy(r, &t[0], sizeof(sp_point)); 1295 memcpy(r, &t[0], sizeof(sp_point));
801 1296
@@ -809,7 +1304,7 @@ static void sp_256_ecc_mulmod_10(sp_point* r, const sp_point* g, const sp_digit*
809 * k Scalar to multiply by. 1304 * k Scalar to multiply by.
810 * map Indicates whether to convert result to affine. 1305 * map Indicates whether to convert result to affine.
811 */ 1306 */
812static void sp_256_ecc_mulmod_base_10(sp_point* r, sp_digit* k /*, int map*/) 1307static void sp_256_ecc_mulmod_base_8(sp_point* r, sp_digit* k /*, int map*/)
813{ 1308{
814 /* Since this function is called only once, save space: 1309 /* Since this function is called only once, save space:
815 * don't have "static const sp_point p256_base = {...}", 1310 * don't have "static const sp_point p256_base = {...}",
@@ -826,7 +1321,7 @@ static void sp_256_ecc_mulmod_base_10(sp_point* r, sp_digit* k /*, int map*/)
826 1321
827 sp_256_point_from_bin2x32(&p256_base, p256_base_bin); 1322 sp_256_point_from_bin2x32(&p256_base, p256_base_bin);
828 1323
829 sp_256_ecc_mulmod_10(r, &p256_base, k /*, map*/); 1324 sp_256_ecc_mulmod_8(r, &p256_base, k /*, map*/);
830} 1325}
831 1326
832/* Multiply the point by the scalar and serialize the X ordinate. 1327/* Multiply the point by the scalar and serialize the X ordinate.
@@ -836,7 +1331,7 @@ static void sp_256_ecc_mulmod_base_10(sp_point* r, sp_digit* k /*, int map*/)
836 * pub2x32 Point to multiply. 1331 * pub2x32 Point to multiply.
837 * out32 Buffer to hold X ordinate. 1332 * out32 Buffer to hold X ordinate.
838 */ 1333 */
839static void sp_ecc_secret_gen_256(const sp_digit priv[10], const uint8_t *pub2x32, uint8_t* out32) 1334static void sp_ecc_secret_gen_256(const sp_digit priv[8], const uint8_t *pub2x32, uint8_t* out32)
840{ 1335{
841 sp_point point[1]; 1336 sp_point point[1];
842 1337
@@ -847,66 +1342,51 @@ static void sp_ecc_secret_gen_256(const sp_digit priv[10], const uint8_t *pub2x3
847 dump_hex(" %s\n", pub2x32 + 32, 32); 1342 dump_hex(" %s\n", pub2x32 + 32, 32);
848 1343
849 sp_256_point_from_bin2x32(point, pub2x32); 1344 sp_256_point_from_bin2x32(point, pub2x32);
850 dump_hex("point->x %s\n", point->x, sizeof(point->x)); 1345 dump_512("point->x %s\n", point->x);
851 dump_hex("point->y %s\n", point->y, sizeof(point->y)); 1346 dump_512("point->y %s\n", point->y);
852 1347
853 sp_256_ecc_mulmod_10(point, point, priv); 1348 sp_256_ecc_mulmod_8(point, point, priv);
854 1349
855 sp_256_to_bin(point->x, out32); 1350 sp_256_to_bin_8(point->x, out32);
856 dump_hex("out32: %s\n", out32, 32); 1351 dump_hex("out32: %s\n", out32, 32);
857} 1352}
858 1353
859/* Generates a scalar that is in the range 1..order-1. */ 1354/* Generates a random scalar in [1..order-1] range. */
860#define SIMPLIFY 1 1355static void sp_256_ecc_gen_k_8(sp_digit k[8])
861/* Add 1 to a. (a = a + 1) */
862static void sp_256_add_one_10(sp_digit* a)
863{ 1356{
864 a[0]++; 1357 /* Since 32-bit words are "dense", no need to use
865 sp_256_norm_10(a); 1358 * sp_256_from_bin_8(k, buf) to convert random stream
866} 1359 * to sp_digit array - just store random bits there directly.
867static void sp_256_ecc_gen_k_10(sp_digit k[10]) 1360 */
868{ 1361 tls_get_random(k, 8 * sizeof(k[0]));
869#if !SIMPLIFY
870 /* The order of the curve P256 minus 2. */
871 static const sp_digit p256_order2[10] = {
872 0x063254f,0x272b0bf,0x1e84f3b,0x2b69c5e,0x3bce6fa,
873 0x3ffffff,0x3ffffff,0x00003ff,0x3ff0000,0x03fffff,
874 };
875#endif
876 uint8_t buf[32];
877
878 for (;;) {
879 tls_get_random(buf, sizeof(buf));
880#if FIXED_SECRET 1362#if FIXED_SECRET
881 memset(buf, 0x77, sizeof(buf)); 1363 memset(k, 0x77, 8 * sizeof(k[0]));
882#endif
883 sp_256_from_bin(k, 10, buf, sizeof(buf));
884#if !SIMPLIFY
885 if (sp_256_cmp_10(k, p256_order2) < 0)
886 break;
887#else
888 /* non-loopy version (and not needing p256_order2[]):
889 * if most-significant word seems that k can be larger
890 * than p256_order2, fix it up:
891 */
892 if (k[9] >= 0x03fffff)
893 k[9] = 0x03ffffe;
894 break;
895#endif 1364#endif
896 } 1365
897 sp_256_add_one_10(k); 1366// If scalar is too large, try again (pseudo-code)
898#undef SIMPLIFY 1367// if (k >= 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 - 1) // order of P256
1368// goto pick_another_random;
1369// k++; // ensure non-zero
1370 /* Simpler alternative, at the cost of not choosing some valid
1371 * random values, and slightly non-uniform distribution */
1372 if (k[0] == 0)
1373 k[0] = 1;
1374 if (k[7] >= 0xffffffff)
1375 k[7] = 0xfffffffe;
899} 1376}
900 1377
901/* Makes a random EC key pair. */ 1378/* Makes a random EC key pair. */
902static void sp_ecc_make_key_256(sp_digit privkey[10], uint8_t *pubkey) 1379static void sp_ecc_make_key_256(sp_digit privkey[8], uint8_t *pubkey)
903{ 1380{
904 sp_point point[1]; 1381 sp_point point[1];
905 1382
906 sp_256_ecc_gen_k_10(privkey); 1383 sp_256_ecc_gen_k_8(privkey);
907 sp_256_ecc_mulmod_base_10(point, privkey); 1384 dump_256("privkey %s\n", privkey);
908 sp_256_to_bin(point->x, pubkey); 1385 sp_256_ecc_mulmod_base_8(point, privkey);
909 sp_256_to_bin(point->y, pubkey + 32); 1386 dump_512("point->x %s\n", point->x);
1387 dump_512("point->y %s\n", point->y);
1388 sp_256_to_bin_8(point->x, pubkey);
1389 sp_256_to_bin_8(point->y, pubkey + 32);
910 1390
911 memset(point, 0, sizeof(point)); //paranoia 1391 memset(point, 0, sizeof(point)); //paranoia
912} 1392}
@@ -915,8 +1395,9 @@ void FAST_FUNC curve_P256_compute_pubkey_and_premaster(
915 uint8_t *pubkey2x32, uint8_t *premaster32, 1395 uint8_t *pubkey2x32, uint8_t *premaster32,
916 const uint8_t *peerkey2x32) 1396 const uint8_t *peerkey2x32)
917{ 1397{
918 sp_digit privkey[10]; 1398 sp_digit privkey[8];
919 1399
1400 dump_hex("peerkey2x32: %s\n", peerkey2x32, 64);
920 sp_ecc_make_key_256(privkey, pubkey2x32); 1401 sp_ecc_make_key_256(privkey, pubkey2x32);
921 dump_hex("pubkey: %s\n", pubkey2x32, 32); 1402 dump_hex("pubkey: %s\n", pubkey2x32, 32);
922 dump_hex(" %s\n", pubkey2x32 + 32, 32); 1403 dump_hex(" %s\n", pubkey2x32 + 32, 32);
diff --git a/networking/tls_symmetric.h b/networking/tls_symmetric.h
deleted file mode 100644
index 5e0e4b6d8..000000000
--- a/networking/tls_symmetric.h
+++ /dev/null
@@ -1,511 +0,0 @@
1/*
2 * Copyright (C) 2017 Denys Vlasenko
3 *
4 * Licensed under GPLv2, see file LICENSE in this source tree.
5 */
6
7
8/* The part below is a section of matrixssl-3-7-2b-open/crypto/cryptolib.h
9 * Changes are flagged with //bbox
10 */
11
12/******************************************************************************/
13/* 32-bit Rotates */
14/******************************************************************************/
15#if defined(_MSC_VER)
16/******************************************************************************/
17
18/* instrinsic rotate */
19#include <stdlib.h>
20#pragma intrinsic(_lrotr,_lrotl)
21#define ROR(x,n) _lrotr(x,n)
22#define ROL(x,n) _lrotl(x,n)
23
24/******************************************************************************/
25#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && \
26 !defined(INTEL_CC) && !defined(PS_NO_ASM)
27
28static ALWAYS_INLINE unsigned ROL(unsigned word, int i)
29{
30 if (__builtin_constant_p(i)) { //box
31 // Rotates by constant use fewer registers,
32 // and on many Intel CPUs rotates by %cl take 2 cycles, not 1.
33 asm ("roll %2,%0"
34 :"=r" (word)
35 :"0" (word),"i" (i));
36 return word;
37 } //box
38 asm ("roll %%cl,%0"
39 :"=r" (word)
40 :"0" (word),"c" (i));
41 return word;
42}
43
44static ALWAYS_INLINE unsigned ROR(unsigned word, int i)
45{
46 if (__builtin_constant_p(i)) { //box
47 asm ("rorl %2,%0"
48 :"=r" (word)
49 :"0" (word),"i" (i));
50 return word;
51 } //box
52 asm ("rorl %%cl,%0"
53 :"=r" (word)
54 :"0" (word),"c" (i));
55 return word;
56}
57
58/******************************************************************************/
59#else
60
61/* rotates the hard way */
62#define ROL(x, y) \
63 ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | \
64 (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & \
65 0xFFFFFFFFUL)
66#define ROR(x, y) \
67 ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | \
68 ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
69
70#endif /* 32-bit Rotates */
71/******************************************************************************/
72
73#ifdef HAVE_NATIVE_INT64
74#ifdef _MSC_VER
75 #define CONST64(n) n ## ui64
76#else
77 #define CONST64(n) n ## ULL
78#endif
79#endif
80
81/******************************************************************************/
82/*
83 Endian helper macros
84 */
85#if defined (ENDIAN_NEUTRAL)
86#define STORE32L(x, y) { \
87(y)[3] = (unsigned char)(((x)>>24)&255); \
88(y)[2] = (unsigned char)(((x)>>16)&255); \
89(y)[1] = (unsigned char)(((x)>>8)&255); \
90(y)[0] = (unsigned char)((x)&255); \
91}
92
93#define LOAD32L(x, y) { \
94x = ((unsigned long)((y)[3] & 255)<<24) | \
95((unsigned long)((y)[2] & 255)<<16) | \
96((unsigned long)((y)[1] & 255)<<8) | \
97((unsigned long)((y)[0] & 255)); \
98}
99
100#define STORE64L(x, y) { \
101(y)[7] = (unsigned char)(((x)>>56)&255); \
102(y)[6] = (unsigned char)(((x)>>48)&255); \
103(y)[5] = (unsigned char)(((x)>>40)&255); \
104(y)[4] = (unsigned char)(((x)>>32)&255); \
105(y)[3] = (unsigned char)(((x)>>24)&255); \
106(y)[2] = (unsigned char)(((x)>>16)&255); \
107(y)[1] = (unsigned char)(((x)>>8)&255); \
108(y)[0] = (unsigned char)((x)&255); \
109}
110
111#define LOAD64L(x, y) { \
112x = (((uint64)((y)[7] & 255))<<56)|(((uint64)((y)[6] & 255))<<48)| \
113(((uint64)((y)[5] & 255))<<40)|(((uint64)((y)[4] & 255))<<32)| \
114(((uint64)((y)[3] & 255))<<24)|(((uint64)((y)[2] & 255))<<16)| \
115(((uint64)((y)[1] & 255))<<8)|(((uint64)((y)[0] & 255))); \
116}
117
118#define STORE32H(x, y) { \
119(y)[0] = (unsigned char)(((x)>>24)&255); \
120(y)[1] = (unsigned char)(((x)>>16)&255); \
121(y)[2] = (unsigned char)(((x)>>8)&255); \
122(y)[3] = (unsigned char)((x)&255); \
123}
124
125#define LOAD32H(x, y) { \
126x = ((unsigned long)((y)[0] & 255)<<24) | \
127((unsigned long)((y)[1] & 255)<<16) | \
128((unsigned long)((y)[2] & 255)<<8) | \
129((unsigned long)((y)[3] & 255)); \
130}
131
132#define STORE64H(x, y) { \
133(y)[0] = (unsigned char)(((x)>>56)&255); \
134(y)[1] = (unsigned char)(((x)>>48)&255); \
135(y)[2] = (unsigned char)(((x)>>40)&255); \
136(y)[3] = (unsigned char)(((x)>>32)&255); \
137(y)[4] = (unsigned char)(((x)>>24)&255); \
138(y)[5] = (unsigned char)(((x)>>16)&255); \
139(y)[6] = (unsigned char)(((x)>>8)&255); \
140(y)[7] = (unsigned char)((x)&255); \
141}
142
143#define LOAD64H(x, y) { \
144x = (((uint64)((y)[0] & 255))<<56)|(((uint64)((y)[1] & 255))<<48) | \
145(((uint64)((y)[2] & 255))<<40)|(((uint64)((y)[3] & 255))<<32) | \
146(((uint64)((y)[4] & 255))<<24)|(((uint64)((y)[5] & 255))<<16) | \
147(((uint64)((y)[6] & 255))<<8)|(((uint64)((y)[7] & 255))); \
148}
149
150#endif /* ENDIAN_NEUTRAL */
151
152#ifdef ENDIAN_LITTLE
153#define STORE32H(x, y) { \
154(y)[0] = (unsigned char)(((x)>>24)&255); \
155(y)[1] = (unsigned char)(((x)>>16)&255); \
156(y)[2] = (unsigned char)(((x)>>8)&255); \
157(y)[3] = (unsigned char)((x)&255); \
158}
159
160#define LOAD32H(x, y) { \
161x = ((unsigned long)((y)[0] & 255)<<24) | \
162((unsigned long)((y)[1] & 255)<<16) | \
163((unsigned long)((y)[2] & 255)<<8) | \
164((unsigned long)((y)[3] & 255)); \
165}
166
167#define STORE64H(x, y) { \
168(y)[0] = (unsigned char)(((x)>>56)&255); \
169(y)[1] = (unsigned char)(((x)>>48)&255); \
170(y)[2] = (unsigned char)(((x)>>40)&255); \
171(y)[3] = (unsigned char)(((x)>>32)&255); \
172(y)[4] = (unsigned char)(((x)>>24)&255); \
173(y)[5] = (unsigned char)(((x)>>16)&255); \
174(y)[6] = (unsigned char)(((x)>>8)&255); \
175(y)[7] = (unsigned char)((x)&255); \
176}
177
178#define LOAD64H(x, y) { \
179x = (((uint64)((y)[0] & 255))<<56)|(((uint64)((y)[1] & 255))<<48) | \
180(((uint64)((y)[2] & 255))<<40)|(((uint64)((y)[3] & 255))<<32) | \
181(((uint64)((y)[4] & 255))<<24)|(((uint64)((y)[5] & 255))<<16) | \
182(((uint64)((y)[6] & 255))<<8)|(((uint64)((y)[7] & 255))); }
183
184#ifdef ENDIAN_32BITWORD
185#define STORE32L(x, y) { \
186unsigned long __t = (x); memcpy(y, &__t, 4); \
187}
188
189#define LOAD32L(x, y) memcpy(&(x), y, 4);
190
191#define STORE64L(x, y) { \
192(y)[7] = (unsigned char)(((x)>>56)&255); \
193(y)[6] = (unsigned char)(((x)>>48)&255); \
194(y)[5] = (unsigned char)(((x)>>40)&255); \
195(y)[4] = (unsigned char)(((x)>>32)&255); \
196(y)[3] = (unsigned char)(((x)>>24)&255); \
197(y)[2] = (unsigned char)(((x)>>16)&255); \
198(y)[1] = (unsigned char)(((x)>>8)&255); \
199(y)[0] = (unsigned char)((x)&255); \
200}
201
202#define LOAD64L(x, y) { \
203x = (((uint64)((y)[7] & 255))<<56)|(((uint64)((y)[6] & 255))<<48)| \
204(((uint64)((y)[5] & 255))<<40)|(((uint64)((y)[4] & 255))<<32)| \
205(((uint64)((y)[3] & 255))<<24)|(((uint64)((y)[2] & 255))<<16)| \
206(((uint64)((y)[1] & 255))<<8)|(((uint64)((y)[0] & 255))); \
207}
208
209#else /* 64-bit words then */
210#define STORE32L(x, y) \
211{ unsigned long __t = (x); memcpy(y, &__t, 4); }
212
213#define LOAD32L(x, y) \
214{ memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
215
216#define STORE64L(x, y) \
217{ uint64 __t = (x); memcpy(y, &__t, 8); }
218
219#define LOAD64L(x, y) \
220{ memcpy(&(x), y, 8); }
221
222#endif /* ENDIAN_64BITWORD */
223#endif /* ENDIAN_LITTLE */
224
225#ifdef ENDIAN_BIG
226#define STORE32L(x, y) { \
227(y)[3] = (unsigned char)(((x)>>24)&255); \
228(y)[2] = (unsigned char)(((x)>>16)&255); \
229(y)[1] = (unsigned char)(((x)>>8)&255); \
230(y)[0] = (unsigned char)((x)&255); \
231}
232
233#define LOAD32L(x, y) { \
234x = ((unsigned long)((y)[3] & 255)<<24) | \
235((unsigned long)((y)[2] & 255)<<16) | \
236((unsigned long)((y)[1] & 255)<<8) | \
237((unsigned long)((y)[0] & 255)); \
238}
239
240#define STORE64L(x, y) { \
241(y)[7] = (unsigned char)(((x)>>56)&255); \
242(y)[6] = (unsigned char)(((x)>>48)&255); \
243(y)[5] = (unsigned char)(((x)>>40)&255); \
244(y)[4] = (unsigned char)(((x)>>32)&255); \
245(y)[3] = (unsigned char)(((x)>>24)&255); \
246(y)[2] = (unsigned char)(((x)>>16)&255); \
247(y)[1] = (unsigned char)(((x)>>8)&255); \
248(y)[0] = (unsigned char)((x)&255); \
249}
250
251#define LOAD64L(x, y) { \
252x = (((uint64)((y)[7] & 255))<<56)|(((uint64)((y)[6] & 255))<<48) | \
253(((uint64)((y)[5] & 255))<<40)|(((uint64)((y)[4] & 255))<<32) | \
254(((uint64)((y)[3] & 255))<<24)|(((uint64)((y)[2] & 255))<<16) | \
255(((uint64)((y)[1] & 255))<<8)|(((uint64)((y)[0] & 255))); \
256}
257
258#ifdef ENDIAN_32BITWORD
259#define STORE32H(x, y) \
260{ unsigned int __t = (x); memcpy(y, &__t, 4); }
261
262#define LOAD32H(x, y) memcpy(&(x), y, 4);
263
264#define STORE64H(x, y) { \
265(y)[0] = (unsigned char)(((x)>>56)&255); \
266(y)[1] = (unsigned char)(((x)>>48)&255); \
267(y)[2] = (unsigned char)(((x)>>40)&255); \
268(y)[3] = (unsigned char)(((x)>>32)&255); \
269(y)[4] = (unsigned char)(((x)>>24)&255); \
270(y)[5] = (unsigned char)(((x)>>16)&255); \
271(y)[6] = (unsigned char)(((x)>>8)&255); \
272(y)[7] = (unsigned char)((x)&255); \
273}
274
275#define LOAD64H(x, y) { \
276x = (((uint64)((y)[0] & 255))<<56)|(((uint64)((y)[1] & 255))<<48)| \
277(((uint64)((y)[2] & 255))<<40)|(((uint64)((y)[3] & 255))<<32)| \
278(((uint64)((y)[4] & 255))<<24)|(((uint64)((y)[5] & 255))<<16)| \
279(((uint64)((y)[6] & 255))<<8)| (((uint64)((y)[7] & 255))); \
280}
281
282#else /* 64-bit words then */
283
284#define STORE32H(x, y) \
285{ unsigned long __t = (x); memcpy(y, &__t, 4); }
286
287#define LOAD32H(x, y) \
288{ memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
289
290#define STORE64H(x, y) \
291{ uint64 __t = (x); memcpy(y, &__t, 8); }
292
293#define LOAD64H(x, y) \
294{ memcpy(&(x), y, 8); }
295
296#endif /* ENDIAN_64BITWORD */
297#endif /* ENDIAN_BIG */
298
299#ifdef HAVE_NATIVE_INT64
300#define ROL64c(x, y) \
301( (((x)<<((uint64)(y)&63)) | \
302(((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((uint64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
303
304#define ROR64c(x, y) \
305( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((uint64)(y)&CONST64(63))) | \
306((x)<<((uint64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
307#endif /* HAVE_NATIVE_INT64 */
308/******************************************************************************/
309
310
311
312/* The part below is taken almost verbatim from matrixssl-3-7-2b-open/crypto/symmetric/.
313 * Changes are flagged with //bbox
314 */
315
316/**
317 * @file symmetric.h
318 * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master)
319 *
320 * Header for internal symmetric key cryptography support.
321 */
322/*
323 * Copyright (c) 2013-2015 INSIDE Secure Corporation
324 * Copyright (c) PeerSec Networks, 2002-2011
325 * All Rights Reserved
326 *
327 * The latest version of this code is available at http://www.matrixssl.org
328 *
329 * This software is open source; you can redistribute it and/or modify
330 * it under the terms of the GNU General Public License as published by
331 * the Free Software Foundation; either version 2 of the License, or
332 * (at your option) any later version.
333 *
334 * This General Public License does NOT permit incorporating this software
335 * into proprietary programs. If you are unable to comply with the GPL, a
336 * commercial license for this software may be purchased from INSIDE at
337 * http://www.insidesecure.com/eng/Company/Locations
338 *
339 * This program is distributed in WITHOUT ANY WARRANTY; without even the
340 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
341 * See the GNU General Public License for more details.
342 *
343 * You should have received a copy of the GNU General Public License
344 * along with this program; if not, write to the Free Software
345 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
346 * http://www.gnu.org/copyleft/gpl.html
347 */
348/******************************************************************************/
349
350#ifndef _h_PS_SYMMETRIC
351#define _h_PS_SYMMETRIC
352
353/******************************************************************************/
354#ifdef USE_AES
355/******************************************************************************/
356
357
358#ifndef USE_AES_CBC_EXTERNAL
359typedef struct {
360 uint32 eK[64], dK[64];
361 int32 Nr;
362} psAesKey_t;
363
364typedef struct {
365 int32 blocklen;
366 unsigned char IV[16];
367 psAesKey_t key;
368#if defined(USE_AES_GCM) || defined(USE_AES_CCM)
369 unsigned char EncCtr[16];
370 unsigned char CtrBlock[16];
371#endif
372#ifdef USE_AES_GCM
373 unsigned char gInit[16];
374 uint32 TagTemp[4];
375 unsigned char Hash_SubKey[16];
376 uint32 ProcessedBitCount[4];
377 uint32 InputBufferCount;
378 uint32 OutputBufferCount;
379 union
380 {
381 unsigned char Buffer[128];
382 uint32 BufferAlignment;
383 } Input;
384#endif /* USE_AES_GCM */
385#ifdef USE_AES_CCM
386 uint32_t ccmTagTemp[16 / sizeof(uint32_t)]; /* 32 */
387 union
388 {
389 /* Used for formatting IV. */
390 uint8_t Temporary[16];
391 /* Used for processing Mac. */
392 uint8_t Y0[16];
393 } u; /* 48 */
394#endif /* USE_AES_CCM */
395} psAesCipher_t;
396#endif /* USE_AES_CBC_EXTERNAL */
397
398#endif /* USE_AES */
399
400#ifdef USE_IDEA
401#define SSL_IDEA_KEY_LEN 16
402#define SSL_IDEA_IV_LEN 8
403#define SSL_IDEA_BLOCK_LEN 8
404
405typedef struct {
406 uint16 key_schedule[52];
407} psIdeaKey_t;
408
409typedef struct {
410 psIdeaKey_t key;
411 uint32 IV[2];
412 short for_encryption;
413 short inverted;
414} idea_CBC;
415#endif
416/******************************************************************************/
417
418/******************************************************************************/
419#ifdef USE_SEED
420/******************************************************************************/
421#define SSL_SEED_KEY_LEN 16
422#define SSL_SEED_IV_LEN 16
423
424
425typedef struct {
426 uint32 K[32], dK[32];
427} psSeedKey_t;
428
429typedef struct {
430 int32 blocklen;
431 unsigned char IV[16];
432 psSeedKey_t key;
433} seed_CBC;
434
435#endif /* USE_SEED */
436/******************************************************************************/
437
438/******************************************************************************/
439#if defined(USE_3DES) || defined(USE_DES)
440/******************************************************************************/
441#define DES3_KEY_LEN 24
442#define DES3_IV_LEN 8
443#define DES_KEY_LEN 8
444
445typedef struct {
446 uint32 ek[3][32], dk[3][32];
447} psDes3Key_t;
448
449/*
450 A block cipher CBC structure
451 */
452typedef struct {
453 int32 blocklen;
454 unsigned char IV[8];
455 psDes3Key_t key;
456} des3_CBC;
457
458#endif /* USE_3DES || USE_DES */
459/******************************************************************************/
460
461/******************************************************************************/
462#ifdef USE_ARC4
463typedef struct {
464 unsigned char state[256];
465 uint32 byteCount;
466 unsigned char x;
467 unsigned char y;
468} psRc4Key_t;
469#endif /* USE_ARC4 */
470/******************************************************************************/
471#ifdef USE_RC2
472typedef struct {
473 unsigned xkey[64];
474} psRc2Key_t;
475
476typedef struct {
477 int32 blocklen;
478 unsigned char IV[8];
479 psRc2Key_t key;
480} rc2_CBC;
481#endif /* USE_RC2 */
482/******************************************************************************/
483/* Universal types and defines */
484/******************************************************************************/
485#define MAXBLOCKSIZE 24
486
487typedef union {
488#ifdef USE_RC2
489 rc2_CBC rc2;
490#endif
491#ifdef USE_ARC4
492 psRc4Key_t arc4;
493#endif
494#ifdef USE_3DES
495 des3_CBC des3;
496#endif
497#ifdef USE_AES
498 psAesCipher_t aes;
499#endif
500#ifdef USE_SEED
501 seed_CBC seed;
502#endif
503#ifdef USE_IDEA
504 idea_CBC idea;
505#endif
506} psCipherContext_t;
507
508#define byte(x, n) (((x) >> (8 * (n))) & 255)
509
510#endif /* _h_PS_SYMMETRIC */
511/******************************************************************************/
diff --git a/networking/wget.c b/networking/wget.c
index a5369be22..85a04eaba 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -135,7 +135,8 @@
135 135
136//usage:#define wget_trivial_usage 136//usage:#define wget_trivial_usage
137//usage: IF_FEATURE_WGET_LONG_OPTIONS( 137//usage: IF_FEATURE_WGET_LONG_OPTIONS(
138//usage: "[-cqS] [--spider] [-O FILE] [-o LOGFILE] [--header 'HEADER: VALUE'] [-Y on/off]\n" 138//usage: "[-cqS] [--spider] [-O FILE] [-o LOGFILE] [--header STR]\n"
139//usage: " [--post-data STR | --post-file FILE] [-Y on/off]\n"
139/* Since we ignore these opts, we don't show them in --help */ 140/* Since we ignore these opts, we don't show them in --help */
140/* //usage: " [--no-cache] [--passive-ftp] [-t TRIES]" */ 141/* //usage: " [--no-cache] [--passive-ftp] [-t TRIES]" */
141/* //usage: " [-nv] [-nc] [-nH] [-np]" */ 142/* //usage: " [-nv] [-nc] [-nH] [-np]" */
@@ -148,6 +149,9 @@
148//usage: "Retrieve files via HTTP or FTP\n" 149//usage: "Retrieve files via HTTP or FTP\n"
149//usage: IF_FEATURE_WGET_LONG_OPTIONS( 150//usage: IF_FEATURE_WGET_LONG_OPTIONS(
150//usage: "\n --spider Only check URL existence: $? is 0 if exists" 151//usage: "\n --spider Only check URL existence: $? is 0 if exists"
152//usage: "\n --header STR Add STR (of form 'header: value') to headers"
153//usage: "\n --post-data STR Send STR using POST method"
154//usage: "\n --post-file FILE Send FILE using POST method"
151//usage: IF_FEATURE_WGET_OPENSSL( 155//usage: IF_FEATURE_WGET_OPENSSL(
152//usage: "\n --no-check-certificate Don't validate the server's certificate" 156//usage: "\n --no-check-certificate Don't validate the server's certificate"
153//usage: ) 157//usage: )
@@ -244,6 +248,7 @@ struct globals {
244 char *dir_prefix; 248 char *dir_prefix;
245#if ENABLE_FEATURE_WGET_LONG_OPTIONS 249#if ENABLE_FEATURE_WGET_LONG_OPTIONS
246 char *post_data; 250 char *post_data;
251 char *post_file;
247 char *extra_headers; 252 char *extra_headers;
248 unsigned char user_headers; /* Headers mentioned by the user */ 253 unsigned char user_headers; /* Headers mentioned by the user */
249#endif 254#endif
@@ -292,10 +297,13 @@ enum {
292 WGET_OPT_POST_DATA = (1 << 12) * ENABLE_FEATURE_WGET_LONG_OPTIONS, 297 WGET_OPT_POST_DATA = (1 << 12) * ENABLE_FEATURE_WGET_LONG_OPTIONS,
293 WGET_OPT_SPIDER = (1 << 13) * ENABLE_FEATURE_WGET_LONG_OPTIONS, 298 WGET_OPT_SPIDER = (1 << 13) * ENABLE_FEATURE_WGET_LONG_OPTIONS,
294 WGET_OPT_NO_CHECK_CERT = (1 << 14) * ENABLE_FEATURE_WGET_LONG_OPTIONS, 299 WGET_OPT_NO_CHECK_CERT = (1 << 14) * ENABLE_FEATURE_WGET_LONG_OPTIONS,
300 WGET_OPT_POST_FILE = (1 << 15) * ENABLE_FEATURE_WGET_LONG_OPTIONS,
295 /* hijack this bit for other than opts purposes: */ 301 /* hijack this bit for other than opts purposes: */
296 WGET_NO_FTRUNCATE = (1 << 31) 302 WGET_NO_FTRUNCATE = (1 << 31)
297}; 303};
298 304
305#define WGET_OPT_POST (WGET_OPT_POST_DATA | WGET_OPT_POST_FILE)
306
299enum { 307enum {
300 PROGRESS_START = -1, 308 PROGRESS_START = -1,
301 PROGRESS_END = 0, 309 PROGRESS_END = 0,
@@ -1246,7 +1254,7 @@ static void download_one_url(const char *url)
1246 target.path); 1254 target.path);
1247 } else { 1255 } else {
1248 SENDFMT(sfp, "%s /%s HTTP/1.1\r\n", 1256 SENDFMT(sfp, "%s /%s HTTP/1.1\r\n",
1249 (option_mask32 & WGET_OPT_POST_DATA) ? "POST" : "GET", 1257 (option_mask32 & WGET_OPT_POST) ? "POST" : "GET",
1250 target.path); 1258 target.path);
1251 } 1259 }
1252 if (!USR_HEADER_HOST) 1260 if (!USR_HEADER_HOST)
@@ -1279,7 +1287,13 @@ static void download_one_url(const char *url)
1279 fputs(G.extra_headers, sfp); 1287 fputs(G.extra_headers, sfp);
1280 } 1288 }
1281 1289
1282 if (option_mask32 & WGET_OPT_POST_DATA) { 1290 if (option_mask32 & WGET_OPT_POST_FILE) {
1291 int fd = xopen_stdin(G.post_file);
1292 G.post_data = xmalloc_read(fd, NULL);
1293 close(fd);
1294 }
1295
1296 if (G.post_data) {
1283 SENDFMT(sfp, 1297 SENDFMT(sfp,
1284 "Content-Type: application/x-www-form-urlencoded\r\n" 1298 "Content-Type: application/x-www-form-urlencoded\r\n"
1285 "Content-Length: %u\r\n" 1299 "Content-Length: %u\r\n"
@@ -1522,6 +1536,7 @@ IF_DESKTOP( "tries\0" Required_argument "t")
1522 "post-data\0" Required_argument "\xfe" 1536 "post-data\0" Required_argument "\xfe"
1523 "spider\0" No_argument "\xfd" 1537 "spider\0" No_argument "\xfd"
1524 "no-check-certificate\0" No_argument "\xfc" 1538 "no-check-certificate\0" No_argument "\xfc"
1539 "post-file\0" Required_argument "\xfb"
1525 /* Ignored (we always use PASV): */ 1540 /* Ignored (we always use PASV): */
1526IF_DESKTOP( "passive-ftp\0" No_argument "\xf0") 1541IF_DESKTOP( "passive-ftp\0" No_argument "\xf0")
1527 /* Ignored (we don't support caching) */ 1542 /* Ignored (we don't support caching) */
@@ -1565,6 +1580,9 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0")
1565 */ 1580 */
1566 "\0" 1581 "\0"
1567 "-1" /* at least one URL */ 1582 "-1" /* at least one URL */
1583 IF_FEATURE_WGET_LONG_OPTIONS(":\xfe--\xfb")
1584 IF_FEATURE_WGET_LONG_OPTIONS(":\xfe--\xfe")
1585 IF_FEATURE_WGET_LONG_OPTIONS(":\xfb--\xfb")
1568 IF_FEATURE_WGET_LONG_OPTIONS(":\xff::") /* --header is a list */ 1586 IF_FEATURE_WGET_LONG_OPTIONS(":\xff::") /* --header is a list */
1569 LONGOPTS 1587 LONGOPTS
1570 , &G.fname_out, &G.fname_log, &G.dir_prefix, 1588 , &G.fname_out, &G.fname_log, &G.dir_prefix,
@@ -1574,6 +1592,7 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0")
1574 NULL /* -n[ARG] */ 1592 NULL /* -n[ARG] */
1575 IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist) 1593 IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist)
1576 IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_data) 1594 IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_data)
1595 IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_file)
1577 ); 1596 );
1578#if 0 /* option bits debug */ 1597#if 0 /* option bits debug */
1579 if (option_mask32 & WGET_OPT_RETRIES) bb_error_msg("-t NUM"); 1598 if (option_mask32 & WGET_OPT_RETRIES) bb_error_msg("-t NUM");
@@ -1582,6 +1601,7 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0")
1582 if (option_mask32 & WGET_OPT_POST_DATA) bb_error_msg("--post-data"); 1601 if (option_mask32 & WGET_OPT_POST_DATA) bb_error_msg("--post-data");
1583 if (option_mask32 & WGET_OPT_SPIDER) bb_error_msg("--spider"); 1602 if (option_mask32 & WGET_OPT_SPIDER) bb_error_msg("--spider");
1584 if (option_mask32 & WGET_OPT_NO_CHECK_CERT) bb_error_msg("--no-check-certificate"); 1603 if (option_mask32 & WGET_OPT_NO_CHECK_CERT) bb_error_msg("--no-check-certificate");
1604 if (option_mask32 & WGET_OPT_POST_FILE) bb_error_msg("--post-file");
1585 exit(0); 1605 exit(0);
1586#endif 1606#endif
1587 argv += optind; 1607 argv += optind;