History

libsec: various changes to tls (import from 9front)

1. add the curve x25519 to tls, both client and server. it's more faster, immune to timing attacks by design, does not require verifying if the public key is valid, etc etc. server-side has to check if the client supports the curve, so a new function has been introduced to parse the client's extensions. 2. reject weak dhe primes that can be easily cracked with the number field sieve algorithm. this avoids attacks like logjam. 3. stop putting unix time to the first 4 bytes of client/ server random. it can allow fingerprinting, tls 1.3 doesn't recommend it any more and there was a draft to deprecate this behaviour earlier.[1] 4. simply prf code, remove useless cipher enums. [1] https://datatracker.ietf.org/doc/html/draft-mathewson-no-gmtunixtime-00

glenda committed 5 years ago

Commit 4eeb8bc1 parent 0e9b2f41 file · +272 −252Browse files

Unified · Split

libsec/tlshand.c+272−252
@@ -66,18 +66,20 @@ struct TlsSec { · 65 unmodified lines
6666 int psklen;
6767 int clientVers; // version in ClientHello
6868 uchar sec[MasterSecretSize]; // master secret
69− uchar crandom[RandomSize]; // client random
7069 uchar srandom[RandomSize]; // server random
70+ uchar crandom[RandomSize]; // client random
7171
72+ Namedcurve *nc; // selected curve for ECDHE
7273 // diffie hellman state
7374 DHstate dh;
7475 struct {
7576 ECdomain dom;
7677 ECpriv Q;
7778 } ec;
79+ uchar X[32];
7880
7981 // byte generation and handshake checksum
80− void (*prf)(uchar*, int, uchar*, int, char*, uchar*, int, uchar*, int);
82+ void (*prf)(uchar*, int, uchar*, int, char*, uchar*, int);
8183 void (*setFinished)(TlsSec*, HandshakeHash, uchar*, int);
8284 int nfin;
8385 };
@@ -107,7 +109,7 @@ typedef struct Msg{ · 23 unmodified lines
107109 int tag;
108110 union {
109111 struct {
110− int version;
112+ int version;
111113 uchar random[RandomSize];
112114 Bytes* sid;
113115 Ints* ciphers;
@@ -115,7 +117,7 @@ typedef struct Msg{ · 1 unmodified line
115117 Bytes* extensions;
116118 } clientHello;
117119 struct {
118− int version;
120+ int version;
119121 uchar random[RandomSize];
120122 Bytes* sid;
121123 int cipher;
@@ -214,79 +216,36 @@ enum { · 92 unmodified lines
214216
215217 // cipher suites
216218 enum {
217− TLS_NULL_WITH_NULL_NULL = 0x0000,
218− TLS_RSA_WITH_NULL_MD5 = 0x0001,
219− TLS_RSA_WITH_NULL_SHA = 0x0002,
220− TLS_RSA_EXPORT_WITH_RC4_40_MD5 = 0x0003,
221− TLS_RSA_WITH_RC4_128_MD5 = 0x0004,
222− TLS_RSA_WITH_RC4_128_SHA = 0x0005,
223− TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 0X0006,
224− TLS_RSA_WITH_IDEA_CBC_SHA = 0X0007,
225− TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = 0X0008,
226− TLS_RSA_WITH_DES_CBC_SHA = 0X0009,
227219 TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0X000A,
228− TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0X000B,
229− TLS_DH_DSS_WITH_DES_CBC_SHA = 0X000C,
230− TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0X000D,
231− TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 0X000E,
232− TLS_DH_RSA_WITH_DES_CBC_SHA = 0X000F,
233− TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0X0010,
234− TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0X0011,
235− TLS_DHE_DSS_WITH_DES_CBC_SHA = 0X0012,
236− TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0X0013, // ZZZ must be implemented for tls1.0 compliance
237− TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0X0014,
238− TLS_DHE_RSA_WITH_DES_CBC_SHA = 0X0015,
239220 TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0X0016,
240− TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = 0x0017,
241− TLS_DH_anon_WITH_RC4_128_MD5 = 0x0018,
242− TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = 0X0019,
243− TLS_DH_anon_WITH_DES_CBC_SHA = 0X001A,
244− TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = 0X001B,
245− TLS_RSA_WITH_AES_128_CBC_SHA = 0X002F, // aes, aka rijndael with 128 bit blocks
246− TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0X0030,
247− TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0X0031,
248− TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0X0032,
221+
222+ TLS_RSA_WITH_AES_128_CBC_SHA = 0X002F,
249223 TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0X0033,
250− TLS_DH_anon_WITH_AES_128_CBC_SHA = 0X0034,
251224 TLS_RSA_WITH_AES_256_CBC_SHA = 0X0035,
252− TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0X0036,
253− TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0X0037,
254− TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0X0038,
255225 TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0X0039,
256− TLS_DH_anon_WITH_AES_256_CBC_SHA = 0X003A,
257226 TLS_RSA_WITH_AES_128_CBC_SHA256 = 0X003C,
258227 TLS_RSA_WITH_AES_256_CBC_SHA256 = 0X003D,
259228 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0X0067,
260229
261230 TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C,
262− TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D,
263231 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E,
264− TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F,
265− TLS_DH_RSA_WITH_AES_128_GCM_SHA256 = 0x00A0,
266− TLS_DH_RSA_WITH_AES_256_GCM_SHA384 = 0x00A1,
267− TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2,
268− TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3,
269− TLS_DH_DSS_WITH_AES_128_GCM_SHA256 = 0x00A4,
270− TLS_DH_DSS_WITH_AES_256_GCM_SHA384 = 0x00A5,
271− TLS_DH_anon_WITH_AES_128_GCM_SHA256 = 0x00A6,
272− TLS_DH_anon_WITH_AES_256_GCM_SHA384 = 0x00A7,
273−
274− TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B,
275− TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F,
276232
277233 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013,
278234 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014,
279− TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027,
280235 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023,
236+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027,
281237
282− TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 = 0xCCA8,
283− TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = 0xCCA9,
284− TLS_DHE_RSA_WITH_CHACHA20_POLY1305 = 0xCCAA,
238+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B,
239+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F,
285240
286241 GOOGLE_ECDHE_RSA_WITH_CHACHA20_POLY1305 = 0xCC13,
287242 GOOGLE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = 0xCC14,
288243 GOOGLE_DHE_RSA_WITH_CHACHA20_POLY1305 = 0xCC15,
289244
245+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 = 0xCCA8,
246+ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = 0xCCA9,
247+ TLS_DHE_RSA_WITH_CHACHA20_POLY1305 = 0xCCAA,
248+
290249 TLS_PSK_WITH_CHACHA20_POLY1305 = 0xCCAB,
291250 TLS_PSK_WITH_AES_128_CBC_SHA256 = 0x00AE,
292251 TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C,
@@ -300,6 +259,20 @@ enum { · 7 unmodified lines
300259 CompressionMax
301260 };
302261
262+
263+// curves
264+enum {
265+ X25519 = 0x001d,
266+};
267+
268+// extensions
269+enum {
270+ Extsni = 0x0000,
271+ Extec = 0x000a,
272+ Extecp = 0x000b,
273+ Extsigalgs = 0x000d,
274+};
275+
303276 static Algs cipherAlgs[] = {
304277 // ECDHE-ECDSA
305278 {"ccpoly96_aead", "clear", 2*(32+12), TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305},
@@ -343,6 +316,7 @@ static uchar compressors[] = { · 37 unmodified lines
343316 };
344317
345318 static Namedcurve namedcurves[] = {
319+ X25519, nil,
346320 0x0017, secp256r1,
347321 0x0018, secp384r1,
348322 };
@@ -401,7 +375,7 @@ static int isPSK(int tlsid); · 52 unmodified lines
401375 static int isECDSA(int tlsid);
402376
403377 static int setAlgs(TlsConnection *c, int a);
404−static int okCipher(Ints *cv, int ispsk);
378+static int okCipher(Ints *cv, int ispsk, int canec);
405379 static int okCompression(Bytes *cv);
406380 static int initCiphers(void);
407381 static Ints* makeciphers(int ispsk);
@@ -412,7 +386,7 @@ static void factotum_rsa_close(AuthRpc *rpc); · 4 unmodified lines
412386
413387 static void tlsSecInits(TlsSec *sec, int cvers, uchar *crandom);
414388 static int tlsSecRSAs(TlsSec *sec, Bytes *epm);
415−static Bytes* tlsSecECDHEs1(TlsSec *sec, Namedcurve *nc);
389+static Bytes* tlsSecECDHEs1(TlsSec *sec);
416390 static int tlsSecECDHEs2(TlsSec *sec, Bytes *Yc);
417391 static void tlsSecInitc(TlsSec *sec, int cvers);
418392 static Bytes* tlsSecRSAc(TlsSec *sec, uchar *cert, int ncert);
@@ -458,12 +432,13 @@ tlsServer(int fd, TLSconn *conn) · 39 unmodified lines
458432 {
459433 char buf[8];
460434 char dname[64];
435+ uchar seed[2*RandomSize];
461436 int n, data, ctl, hand;
462437 TlsConnection *tls;
463438
464439 if(conn == nil)
465440 return -1;
466− ctl = open("#a/tls/clone", ORDWR);
441+ ctl = open("#a/tls/clone", ORDWR|OCEXEC);
467442 if(ctl < 0)
468443 return -1;
469444 n = read(ctl, buf, sizeof(buf)-1);
@@ -474,7 +449,7 @@ tlsServer(int fd, TLSconn *conn) · 4 unmodified lines
474449 buf[n] = 0;
475450 snprint(conn->dir, sizeof(conn->dir), "#a/tls/%s", buf);
476451 snprint(dname, sizeof(dname), "#a/tls/%s/hand", buf);
477− hand = open(dname, ORDWR);
452+ hand = open(dname, ORDWR|OCEXEC);
478453 if(hand < 0){
479454 close(ctl);
480455 return -1;
@@ -502,13 +477,15 @@ tlsServer(int fd, TLSconn *conn) · 21 unmodified lines
502477 conn->sessionID = nil;
503478 if(conn->sessionKey != nil
504479 && conn->sessionType != nil
505− && strcmp(conn->sessionType, "ttls") == 0)
480+ && strcmp(conn->sessionType, "ttls") == 0){
481+ memmove(seed, tls->sec->crandom, RandomSize);
482+ memmove(seed+RandomSize, tls->sec->srandom, RandomSize);
506483 tls->sec->prf(
507484 conn->sessionKey, conn->sessionKeylen,
508485 tls->sec->sec, MasterSecretSize,
509486 conn->sessionConst,
510− tls->sec->crandom, RandomSize,
511− tls->sec->srandom, RandomSize);
487+ seed, sizeof(seed));
488+ }
512489 tlsConnectionFree(tls);
513490 close(fd);
514491 return data;
@@ -530,7 +507,7 @@ tlsClientExtensions(TLSconn *conn, int *plen) · 15 unmodified lines
530507 b = erealloc(b, m + 2+2+2+1+2+n);
531508 p = b + m;
532509
533− put16(p, 0), p += 2; /* Type: server_name */
510+ put16(p, Extsni), p += 2; /* Type: server_name */
534511 put16(p, 2+1+2+n), p += 2; /* Length */
535512 put16(p, 1+2+n), p += 2; /* Server Name list length */
536513 *p++ = 0; /* Server Name Type: host_name */
@@ -539,26 +516,26 @@ tlsClientExtensions(TLSconn *conn, int *plen) · 2 unmodified lines
539516 p += n;
540517 }
541518
542− // ECDHE
519+ // Elliptic Curves (also called Supported Groups)
543520 if(ProtocolVersion >= TLS10Version){
544521 m = p - b;
545522 b = erealloc(b, m + 2+2+2+nelem(namedcurves)*2 + 2+2+1+nelem(pointformats));
546523 p = b + m;
547524
548525 n = nelem(namedcurves);
549− put16(p, 0x000a), p += 2; /* Type: elliptic_curves */
526+ put16(p, Extec), p += 2; /* Type: elliptic_curves / supported_groups */
550527 put16(p, (n+1)*2), p += 2; /* Length */
551528 put16(p, n*2), p += 2; /* Elliptic Curves Length */
552− for(i=0; i < n; i++){ /* Elliptic curves */
529+ for(i=0; i < n; i++){ /* Elliptic Curves */
553530 put16(p, namedcurves[i].tlsid);
554531 p += 2;
555532 }
556533
557534 n = nelem(pointformats);
558− put16(p, 0x000b), p += 2; /* Type: ec_point_formats */
535+ put16(p, Extecp), p += 2; /* Type: ec_point_formats */
559536 put16(p, n+1), p += 2; /* Length */
560537 *p++ = n; /* EC point formats Length */
561− for(i=0; i < n; i++) /* Elliptic curves point formats */
538+ for(i=0; i < n; i++) /* EC point formats */
562539 *p++ = pointformats[i];
563540 }
564541
@@ -570,7 +547,7 @@ tlsClientExtensions(TLSconn *conn, int *plen) · 5 unmodified lines
570547 b = erealloc(b, m + 2+2+2+n*2);
571548 p = b + m;
572549
573− put16(p, 0x000d), p += 2;
550+ put16(p, Extsigalgs), p += 2;
574551 put16(p, n*2 + 2), p += 2;
575552 put16(p, n*2), p += 2;
576553 for(i=0; i < n; i++){
@@ -590,13 +567,14 @@ tlsClient(int fd, TLSconn *conn) · 13 unmodified lines
590567 {
591568 char buf[8];
592569 char dname[64];
570+ uchar seed[2*RandomSize];
593571 int n, data, ctl, hand;
594572 TlsConnection *tls;
595573 uchar *ext;
596574
597575 if(conn == nil)
598576 return -1;
599− ctl = open("#a/tls/clone", ORDWR);
577+ ctl = open("#a/tls/clone", ORDWR|OCEXEC);
600578 if(ctl < 0)
601579 return -1;
602580 n = read(ctl, buf, sizeof(buf)-1);
@@ -607,7 +585,7 @@ tlsClient(int fd, TLSconn *conn) · 4 unmodified lines
607585 buf[n] = 0;
608586 snprint(conn->dir, sizeof(conn->dir), "#a/tls/%s", buf);
609587 snprint(dname, sizeof(dname), "#a/tls/%s/hand", buf);
610− hand = open(dname, ORDWR);
588+ hand = open(dname, ORDWR|OCEXEC);
611589 if(hand < 0){
612590 close(ctl);
613591 return -1;
@@ -645,13 +623,15 @@ tlsClient(int fd, TLSconn *conn) · 31 unmodified lines
645623 conn->sessionID = nil;
646624 if(conn->sessionKey != nil
647625 && conn->sessionType != nil
648− && strcmp(conn->sessionType, "ttls") == 0)
626+ && strcmp(conn->sessionType, "ttls") == 0){
627+ memmove(seed, tls->sec->crandom, RandomSize);
628+ memmove(seed+RandomSize, tls->sec->srandom, RandomSize);
649629 tls->sec->prf(
650630 conn->sessionKey, conn->sessionKeylen,
651631 tls->sec->sec, MasterSecretSize,
652632 conn->sessionConst,
653− tls->sec->crandom, RandomSize,
654− tls->sec->srandom, RandomSize);
633+ seed, sizeof(seed));
634+ }
655635 tlsConnectionFree(tls);
656636 close(fd);
657637 return data;
@@ -669,6 +649,53 @@ countchain(PEMChain *p) · 11 unmodified lines
669649 return i;
670650 }
671651
652+static int
653+checkClientExtensions(TlsConnection *c, Bytes *ext)
654+{
655+ uchar *p, *e;
656+ int i, j, n;
657+
658+ p = ext->data;
659+ e = p+ext->len;
660+ while(p < e){
661+ if(e-p < 2)
662+ goto Short;
663+ switch(get16(p)){
664+ case Extec:
665+ p += 2;
666+ n = get16(p);
667+ if(e-p < n || n < 2)
668+ goto Short;
669+ p += 2;
670+ n = get16(p);
671+ p += 2;
672+ if(e-p < n || n & 1 || n == 0)
673+ goto Short;
674+ for(i = 0; i < nelem(namedcurves) && c->sec->nc == nil; i++)
675+ for(j = 0; j < n; j += 2)
676+ if(namedcurves[i].tlsid == get16(p+j)){
677+ c->sec->nc = &namedcurves[i];
678+ break;
679+ }
680+ p += n;
681+ break;
682+ default:
683+ p += 2;
684+ n = get16(p);
685+ p += 2;
686+ if(e-p < n)
687+ goto Short;
688+ p += n;
689+ break;
690+ }
691+ }
692+
693+ return 0;
694+Short:
695+ tlsError(c, EDecodeError, "clienthello extensions has invalid length");
696+ return -1;
697+}
698+
672699 static TlsConnection *
673700 tlsServer2(int ctl, int hand,
674701 uchar *cert, int certlen,
@@ -712,19 +739,6 @@ tlsServer2(int ctl, int hand, · 37 unmodified lines
712739 tlsError(c, EInappropriateFallback, "inappropriate fallback");
713740 goto Err;
714741 }
715− cipher = okCipher(m.u.clientHello.ciphers, psklen > 0);
716− if(cipher < 0 || !setAlgs(c, cipher)) {
717− tlsError(c, EHandshakeFailure, "no matching cipher suite");
718− goto Err;
719− }
720− compressor = okCompression(m.u.clientHello.compressors);
721− if(compressor < 0) {
722− tlsError(c, EHandshakeFailure, "no matching compressor");
723− goto Err;
724− }
725− if(trace)
726− trace(" cipher %x, compressor %x\n", cipher, compressor);
727−
728742 tlsSecInits(c->sec, m.u.clientHello.version, m.u.clientHello.random);
729743 tlsSecVers(c->sec, c->version);
730744 if(psklen > 0){
@@ -744,6 +758,20 @@ tlsServer2(int ctl, int hand, · 13 unmodified lines
744758 goto Err;
745759 }
746760 }
761+ if(checkClientExtensions(c, m.u.clientHello.extensions) < 0)
762+ goto Err;
763+ cipher = okCipher(m.u.clientHello.ciphers, psklen > 0, c->sec->nc != nil);
764+ if(cipher < 0 || !setAlgs(c, cipher)) {
765+ tlsError(c, EHandshakeFailure, "no matching cipher suite");
766+ goto Err;
767+ }
768+ compressor = okCompression(m.u.clientHello.compressors);
769+ if(compressor < 0) {
770+ tlsError(c, EHandshakeFailure, "no matching compressor");
771+ goto Err;
772+ }
773+ if(trace)
774+ trace(" cipher %x, compressor %x\n", cipher, compressor);
747775 msgClear(&m);
748776
749777 m.tag = HServerHello;
@@ -768,11 +796,9 @@ tlsServer2(int ctl, int hand, · 18 unmodified lines
768796 }
769797
770798 if(isECDHE(cipher)){
771− Namedcurve *nc = &namedcurves[0]; /* secp256r1 */
772−
773799 m.tag = HServerKeyExchange;
774− m.u.serverKeyExchange.curve = nc->tlsid;
775− m.u.serverKeyExchange.dh_parameters = tlsSecECDHEs1(c->sec, nc);
800+ m.u.serverKeyExchange.curve = c->sec->nc->tlsid;
801+ m.u.serverKeyExchange.dh_parameters = tlsSecECDHEs1(c->sec);
776802 if(m.u.serverKeyExchange.dh_parameters == nil){
777803 tlsError(c, EInternalError, "can't set DH parameters");
778804 goto Err;
@@ -893,7 +919,9 @@ tlsSecDHEc(TlsSec *sec, Bytes *p, Bytes *g, Bytes *Ys) · 114 unmodified lines
893919
894920 if(p == nil || g == nil || Ys == nil)
895921 return nil;
896−
922+ // reject dh primes that is susceptible to logjam
923+ if(p->len <= 1024/8)
924+ return nil;
897925 Yc = nil;
898926 P = bytestomp(p);
899927 G = bytestomp(g);
@@ -924,49 +952,65 @@ Out: · 24 unmodified lines
924952 static Bytes*
925953 tlsSecECDHEc(TlsSec *sec, int curve, Bytes *Ys)
926954 {
955+ static char zero[32] = {0};
927956 ECdomain *dom = &sec->ec.dom;
928957 ECpriv *Q = &sec->ec.Q;
929− Namedcurve *nc;
930958 ECpub *pub;
931959 ECpoint K;
960+ Namedcurve *nc;
932961 Bytes *Yc;
962+ Bytes *Z;
933963 int n;
934964
935965 if(Ys == nil)
936966 return nil;
937− for(nc = namedcurves; nc != &namedcurves[nelem(namedcurves)]; nc++)
938− if(nc->tlsid == curve)
939− goto Found;
940− return nil;
941−
942−Found:
943− ecdominit(dom, nc->init);
944− pub = ecdecodepub(dom, Ys->data, Ys->len);
945− if(pub == nil)
946− return nil;
947967
948− memset(Q, 0, sizeof(*Q));
949− Q->a.x = mpnew(0);
950− Q->a.y = mpnew(0);
951− Q->d = mpnew(0);
968+ if(curve == X25519){
969+ if(Ys->len != 32)
970+ return nil;
971+ Yc = newbytes(32);
972+ curve25519_dh_new(sec->X, Yc->data);
973+ Z = newbytes(32);
974+ curve25519_dh_finish(sec->X, Ys->data, Z->data);
975+ // rfc wants us to terminate the connection if
976+ // shared secret == all zeroes.
977+ if(tsmemcmp(Z->data, zero, Z->len) == 0){
978+ freebytes(Yc);
979+ freebytes(Z);
980+ return nil;
981+ }
982+ setMasterSecret(sec, Z);
983+ }else{
984+ for(nc = namedcurves; nc->tlsid != curve; nc++)
985+ if(nc == &namedcurves[nelem(namedcurves)])
986+ return nil;
987+ ecdominit(dom, nc->init);
988+ pub = ecdecodepub(dom, Ys->data, Ys->len);
989+ if(pub == nil)
990+ return nil;
952991
953− memset(&K, 0, sizeof(K));
954− K.x = mpnew(0);
955− K.y = mpnew(0);
992+ memset(Q, 0, sizeof(*Q));
993+ Q->x = mpnew(0);
994+ Q->y = mpnew(0);
995+ Q->d = mpnew(0);
956996
957− ecgen(dom, Q);
958− ecmul(dom, pub, Q->d, &K);
997+ memset(&K, 0, sizeof(K));
998+ K.x = mpnew(0);
999+ K.y = mpnew(0);
9591000
960− n = (mpsignif(dom->p)+7)/8;
961− setMasterSecret(sec, mptobytes(K.x, n));
962− Yc = newbytes(1 + 2*n);
963− Yc->len = ecencodepub(dom, (ECpub*)Q, Yc->data, Yc->len);
1001+ ecgen(dom, Q);
1002+ ecmul(dom, pub, Q->d, &K);
9641003
965− mpfree(K.x);
966− mpfree(K.y);
1004+ n = (mpsignif(dom->p)+7)/8;
1005+ setMasterSecret(sec, mptobytes(K.x, n));
1006+ Yc = newbytes(1 + 2*n);
1007+ Yc->len = ecencodepub(dom, Q, Yc->data, Yc->len);
9671008
968− ecpubfree(pub);
1009+ mpfree(K.x);
1010+ mpfree(K.y);
9691011
1012+ ecpubfree(pub);
1013+ }
9701014 return Yc;
9711015 }
9721016
@@ -1049,7 +1093,6 @@ tlsClient2(int ctl, int hand, · 76 unmodified lines
10491093 tlsError(c, EIllegalParameter, "invalid compression");
10501094 goto Err;
10511095 }
1052−
10531096 dhx = isDHE(cipher) || isECDHE(cipher);
10541097 if(!msgRecv(c, &m))
10551098 goto Err;
@@ -1790,8 +1833,7 @@ msgRecv(TlsConnection *c, Msg *m) · 734 unmodified lines
17901833 goto Short;
17911834 Ok:
17921835 if(c->trace)
1793− c->trace("recv %s", msgPrint((char*)c->sendp,
1794− &c->buf[sizeof(c->buf)] - c->sendp, m));
1836+ c->trace("recv %s", msgPrint((char*)c->sendp, &c->buf[sizeof(c->buf)] - c->sendp, m));
17951837 return 1;
17961838 Short:
17971839 tlsError(c, EDecodeError, "handshake message (%d) has invalid length", type);
@@ -2042,8 +2084,8 @@ tlsConnectionFree(TlsConnection *c) · 244 unmodified lines
20422084
20432085 dh_finish(&c->sec->dh, nil);
20442086
2045− mpfree(c->sec->ec.Q.a.x);
2046− mpfree(c->sec->ec.Q.a.y);
2087+ mpfree(c->sec->ec.Q.x);
2088+ mpfree(c->sec->ec.Q.y);
20472089 mpfree(c->sec->ec.Q.d);
20482090 ecdomfree(&c->sec->ec.dom);
20492091
@@ -2141,13 +2183,17 @@ setAlgs(TlsConnection *c, int a) · 91 unmodified lines
21412183 }
21422184
21432185 static int
2144−okCipher(Ints *cv, int ispsk)
2186+okCipher(Ints *cv, int ispsk, int canec)
21452187 {
21462188 int i, c;
21472189
21482190 for(i = 0; i < nelem(cipherAlgs); i++) {
21492191 c = cipherAlgs[i].tlsid;
2150− if(!cipherAlgs[i].ok || isECDSA(c) || isDHE(c) || isPSK(c) != ispsk)
2192+ if(!cipherAlgs[i].ok || isECDSA(c) || isDHE(c))
2193+ continue;
2194+ if(isPSK(c) != ispsk)
2195+ continue;
2196+ if(isECDHE(c) && !canec)
21512197 continue;
21522198 if(lookupid(cv, c) >= 0)
21532199 return c;
@@ -2183,7 +2229,7 @@ initCiphers(void) · 29 unmodified lines
21832229 unlock(&ciphLock);
21842230 return nciphers;
21852231 }
2186− j = open("#a/tls/encalgs", OREAD);
2232+ j = open("#a/tls/encalgs", OREAD|OCEXEC);
21872233 if(j < 0){
21882234 werrstr("can't open #a/tls/encalgs: %r");
21892235 goto out;
@@ -2207,7 +2253,7 @@ initCiphers(void) · 17 unmodified lines
22072253 cipherAlgs[i].ok = ok;
22082254 }
22092255
2210− j = open("#a/tls/hashalgs", OREAD);
2256+ j = open("#a/tls/hashalgs", OREAD|OCEXEC);
22112257 if(j < 0){
22122258 werrstr("can't open #a/tls/hashalgs: %r");
22132259 goto out;
@@ -2266,7 +2312,7 @@ factotum_rsa_open(RSApub *rsapub) · 52 unmodified lines
22662312 AuthRpc *rpc;
22672313
22682314 // start talking to factotum
2269− if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0)
2315+ if((afd = open("/mnt/factotum/rpc", ORDWR|OCEXEC)) < 0)
22702316 return nil;
22712317 if((rpc = auth_allocrpc(afd)) == nil){
22722318 close(afd);
@@ -2318,114 +2364,55 @@ factotum_rsa_close(AuthRpc *rpc) · 45 unmodified lines
23182364 }
23192365
23202366 static void
2321−tlsPmd5(uchar *buf, int nbuf, uchar *key, int nkey, uchar *label, int nlabel, uchar *seed0, int nseed0, uchar *seed1, int nseed1)
2322−{
2323− uchar ai[MD5dlen], tmp[MD5dlen];
2324− int i, n;
2325− MD5state *s;
2326−
2327− // generate a1
2328− s = hmac_md5(label, nlabel, key, nkey, nil, nil);
2329− s = hmac_md5(seed0, nseed0, key, nkey, nil, s);
2330− hmac_md5(seed1, nseed1, key, nkey, ai, s);
2331−
2332− while(nbuf > 0) {
2333− s = hmac_md5(ai, MD5dlen, key, nkey, nil, nil);
2334− s = hmac_md5(label, nlabel, key, nkey, nil, s);
2335− s = hmac_md5(seed0, nseed0, key, nkey, nil, s);
2336− hmac_md5(seed1, nseed1, key, nkey, tmp, s);
2337− n = MD5dlen;
2338− if(n > nbuf)
2339− n = nbuf;
2340− for(i = 0; i < n; i++)
2341− buf[i] ^= tmp[i];
2342− buf += n;
2343− nbuf -= n;
2344− hmac_md5(ai, MD5dlen, key, nkey, tmp, nil);
2345− memmove(ai, tmp, MD5dlen);
2346− }
2347−}
2348−
2349−static void
2350−tlsPsha1(uchar *buf, int nbuf, uchar *key, int nkey, uchar *label, int nlabel, uchar *seed0, int nseed0, uchar *seed1, int nseed1)
2351−{
2352− uchar ai[SHA1dlen], tmp[SHA1dlen];
2353− int i, n;
2354− SHAstate *s;
2355−
2356− // generate a1
2357− s = hmac_sha1(label, nlabel, key, nkey, nil, nil);
2358− s = hmac_sha1(seed0, nseed0, key, nkey, nil, s);
2359− hmac_sha1(seed1, nseed1, key, nkey, ai, s);
2360−
2361− while(nbuf > 0) {
2362− s = hmac_sha1(ai, SHA1dlen, key, nkey, nil, nil);
2363− s = hmac_sha1(label, nlabel, key, nkey, nil, s);
2364− s = hmac_sha1(seed0, nseed0, key, nkey, nil, s);
2365− hmac_sha1(seed1, nseed1, key, nkey, tmp, s);
2366− n = SHA1dlen;
2367− if(n > nbuf)
2368− n = nbuf;
2369− for(i = 0; i < n; i++)
2370− buf[i] ^= tmp[i];
2371− buf += n;
2372− nbuf -= n;
2373− hmac_sha1(ai, SHA1dlen, key, nkey, tmp, nil);
2374− memmove(ai, tmp, SHA1dlen);
2375− }
2376−}
2377−
2378−static void
2379−p_sha256(uchar *buf, int nbuf, uchar *key, int nkey, uchar *label, int nlabel, uchar *seed, int nseed)
2367+tlsP(uchar *buf, int nbuf, uchar *key, int nkey, uchar *label, int nlabel, uchar *seed, int nseed,
2368+ DigestState* (*x)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*), int xlen)
23802369 {
23812370 uchar ai[SHA2_256dlen], tmp[SHA2_256dlen];
2382− SHAstate *s;
2371+ DigestState *s;
23832372 int n;
23842373
2374+ assert(sizeof(ai) <= xlen && sizeof(tmp) <= xlen);
23852375 // generate a1
2386− s = hmac_sha2_256(label, nlabel, key, nkey, nil, nil);
2387− hmac_sha2_256(seed, nseed, key, nkey, ai, s);
2376+ s = x(label, nlabel, key, nkey, nil, nil);
2377+ x(seed, nseed, key, nkey, ai, s);
23882378
23892379 while(nbuf > 0) {
2390− s = hmac_sha2_256(ai, SHA2_256dlen, key, nkey, nil, nil);
2391− s = hmac_sha2_256(label, nlabel, key, nkey, nil, s);
2392− hmac_sha2_256(seed, nseed, key, nkey, tmp, s);
2393− n = SHA2_256dlen;
2380+ s = x(ai, xlen, key, nkey, nil, nil);
2381+ s = x(label, nlabel, key, nkey, nil, s);
2382+ x(seed, nseed, key, nkey, tmp, s);
2383+ n = xlen;
23942384 if(n > nbuf)
23952385 n = nbuf;
23962386 memmove(buf, tmp, n);
23972387 buf += n;
23982388 nbuf -= n;
2399− hmac_sha2_256(ai, SHA2_256dlen, key, nkey, tmp, nil);
2400− memmove(ai, tmp, SHA2_256dlen);
2389+ x(ai, xlen, key, nkey, tmp, nil);
2390+ memmove(ai, tmp, xlen);
24012391 }
24022392 }
24032393
24042394 // fill buf with md5(args)^sha1(args)
24052395 static void
2406−tls10PRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed0, int nseed0, uchar *seed1, int nseed1)
2396+tls10PRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed, int nseed)
24072397 {
24082398 int nlabel = strlen(label);
24092399 int n = (nkey + 1) >> 1;
24102400
2411− memset(buf, 0, nbuf);
2412− tlsPmd5(buf, nbuf, key, n, (uchar*)label, nlabel, seed0, nseed0, seed1, nseed1);
2413− tlsPsha1(buf, nbuf, key+nkey-n, n, (uchar*)label, nlabel, seed0, nseed0, seed1, nseed1);
2401+ tlsP(buf, nbuf, key, n, (uchar*)label, nlabel, seed, nseed,
2402+ hmac_md5, MD5dlen);
2403+ tlsP(buf, nbuf, key+nkey-n, n, (uchar*)label, nlabel, seed, nseed,
2404+ hmac_sha1, SHA1dlen);
24142405 }
24152406
24162407 static void
2417−tls12PRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed0, int nseed0, uchar *seed1, int nseed1)
2408+tls12PRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed, int nseed)
24182409 {
2419− uchar seed[2*RandomSize];
2420−
2421− assert(nseed0+nseed1 <= sizeof(seed));
2422− memmove(seed, seed0, nseed0);
2423− memmove(seed+nseed0, seed1, nseed1);
2424− p_sha256(buf, nbuf, key, nkey, (uchar*)label, strlen(label), seed, nseed0+nseed1);
2410+ tlsP(buf, nbuf, key, nkey, (uchar*)label, strlen(label), seed, nseed,
2411+ hmac_sha2_256, SHA2_256dlen);
24252412 }
24262413
24272414 static void
2428−sslPRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed0, int nseed0, uchar *seed1, int nseed1)
2415+sslPRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed, int nseed)
24292416 {
24302417 uchar sha1dig[SHA1dlen], md5dig[MD5dlen], tmp[26];
24312418 DigestState *s;
@@ -2440,8 +2427,7 @@ sslPRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed0, in · 8 unmodified lines
24402427 tmp[i] = 'A' - 1 + len;
24412428 s = sha1(tmp, len, nil, nil);
24422429 s = sha1(key, nkey, nil, s);
2443− s = sha1(seed0, nseed0, nil, s);
2444− sha1(seed1, nseed1, sha1dig, s);
2430+ sha1(seed, nseed, sha1dig, s);
24452431 s = md5(key, nkey, nil, nil);
24462432 md5(sha1dig, SHA1dlen, md5dig, s);
24472433 n = MD5dlen;
@@ -2491,18 +2477,18 @@ sslSetFinished(TlsSec *sec, HandshakeHash hsh, uchar *finished, int isclient) · 43 unmodified lines
24912477 static void
24922478 tls10SetFinished(TlsSec *sec, HandshakeHash hsh, uchar *finished, int isclient)
24932479 {
2494− uchar h0[MD5dlen], h1[SHA1dlen];
2480+ uchar h[MD5dlen+SHA1dlen];
24952481 char *label;
24962482
24972483 // get current hash value, but allow further messages to be hashed in
2498− md5(nil, 0, h0, &hsh.md5);
2499− sha1(nil, 0, h1, &hsh.sha1);
2484+ md5(nil, 0, h, &hsh.md5);
2485+ sha1(nil, 0, h+MD5dlen, &hsh.sha1);
25002486
25012487 if(isclient)
25022488 label = "client finished";
25032489 else
25042490 label = "server finished";
2505− tls10PRF(finished, TLSFinishedLen, sec->sec, MasterSecretSize, label, h0, MD5dlen, h1, SHA1dlen);
2491+ tls10PRF(finished, TLSFinishedLen, sec->sec, MasterSecretSize, label, h, sizeof(h));
25062492 }
25072493
25082494 static void
@@ -2518,7 +2504,7 @@ tls12SetFinished(TlsSec *sec, HandshakeHash hsh, uchar *finished, int isclient) · 9 unmodified lines
25182504 label = "client finished";
25192505 else
25202506 label = "server finished";
2521− p_sha256(finished, TLSFinishedLen, sec->sec, MasterSecretSize, (uchar*)label, strlen(label), seed, SHA2_256dlen);
2507+ tls12PRF(finished, TLSFinishedLen, sec->sec, MasterSecretSize, label, seed, SHA2_256dlen);
25222508 }
25232509
25242510 static void
@@ -2528,8 +2514,9 @@ tlsSecInits(TlsSec *sec, int cvers, uchar *crandom) · 3 unmodified lines
25282514 sec->clientVers = cvers;
25292515 memmove(sec->crandom, crandom, RandomSize);
25302516
2531− put32(sec->srandom, time(nil));
2532− genrandom(sec->srandom+4, RandomSize-4);
2517+ // putting time()'s output to the first 4 bytes is no
2518+ // longer recommended and is not useful
2519+ genrandom(sec->srandom, RandomSize);
25332520 }
25342521
25352522 static int
@@ -2554,61 +2541,88 @@ tlsSecRSAs(TlsSec *sec, Bytes *epm) · 18 unmodified lines
25542541 }
25552542
25562543 static Bytes*
2557−tlsSecECDHEs1(TlsSec *sec, Namedcurve *nc)
2544+tlsSecECDHEs1(TlsSec *sec)
25582545 {
25592546 ECdomain *dom = &sec->ec.dom;
25602547 ECpriv *Q = &sec->ec.Q;
25612548 Bytes *par;
25622549 int n;
25632550
2564− ecdominit(dom, nc->init);
2565− memset(Q, 0, sizeof(*Q));
2566− Q->a.x = mpnew(0);
2567− Q->a.y = mpnew(0);
2568− Q->d = mpnew(0);
2569− ecgen(dom, Q);
2570− n = 1 + 2*((mpsignif(dom->p)+7)/8);
2571− par = newbytes(1+2+1+n);
2572− par->data[0] = 3;
2573− put16(par->data+1, nc->tlsid);
2574− n = ecencodepub(dom, (ECpub*)Q, par->data+4, par->len-4);
2575− par->data[3] = n;
2576− par->len = 1+2+1+n;
2577−
2551+ if(sec->nc == nil)
2552+ return nil;
2553+ if(sec->nc->tlsid == X25519){
2554+ par = newbytes(1+2+1+32);
2555+ par->data[0] = 3;
2556+ put16(par->data+1, X25519);
2557+ par->data[3] = 32;
2558+ curve25519_dh_new(sec->X, par->data+4);
2559+ }else{
2560+ ecdominit(dom, sec->nc->init);
2561+ memset(Q, 0, sizeof(*Q));
2562+ Q->x = mpnew(0);
2563+ Q->y = mpnew(0);
2564+ Q->d = mpnew(0);
2565+ ecgen(dom, Q);
2566+ n = 1 + 2*((mpsignif(dom->p)+7)/8);
2567+ par = newbytes(1+2+1+n);
2568+ par->data[0] = 3;
2569+ put16(par->data+1, sec->nc->tlsid);
2570+ n = ecencodepub(dom, Q, par->data+4, par->len-4);
2571+ par->data[3] = n;
2572+ par->len = 1+2+1+n;
2573+ }
25782574 return par;
25792575 }
25802576
25812577 static int
25822578 tlsSecECDHEs2(TlsSec *sec, Bytes *Yc)
25832579 {
2580+ static char zero[32] = {0};
25842581 ECdomain *dom = &sec->ec.dom;
25852582 ECpriv *Q = &sec->ec.Q;
25862583 ECpoint K;
25872584 ECpub *Y;
2585+ Bytes *Z;
25882586
25892587 if(Yc == nil){
25902588 werrstr("no public key");
25912589 return -1;
25922590 }
25932591
2594− if((Y = ecdecodepub(dom, Yc->data, Yc->len)) == nil){
2595− werrstr("bad public key");
2596− return -1;
2597− }
2598−
2599− memset(&K, 0, sizeof(K));
2600− K.x = mpnew(0);
2601− K.y = mpnew(0);
2592+ if(sec->nc->tlsid == X25519){
2593+ if(Yc->len != 32){
2594+ werrstr("bad public key");
2595+ return -1;
2596+ }
2597+ Z = newbytes(32);
2598+ curve25519_dh_finish(sec->X, Yc->data, Z->data);
2599+ // rfc wants us to terminate the connection if
2600+ // shared secret == all zeroes.
2601+ if(tsmemcmp(Z->data, zero, Z->len) == 0){
2602+ werrstr("unlucky shared key");
2603+ freebytes(Z);
2604+ return -1;
2605+ }
2606+ setMasterSecret(sec, Z);
2607+ }else{
2608+ if((Y = ecdecodepub(dom, Yc->data, Yc->len)) == nil){
2609+ werrstr("bad public key");
2610+ return -1;
2611+ }
26022612
2603− ecmul(dom, Y, Q->d, &K);
2613+ memset(&K, 0, sizeof(K));
2614+ K.x = mpnew(0);
2615+ K.y = mpnew(0);
26042616
2605− setMasterSecret(sec, mptobytes(K.x, (mpsignif(dom->p)+7)/8));
2617+ ecmul(dom, Y, Q->d, &K);
26062618
2607− mpfree(K.x);
2608− mpfree(K.y);
2619+ setMasterSecret(sec, mptobytes(K.x, (mpsignif(dom->p)+7)/8));
26092620
2610− ecpubfree(Y);
2621+ mpfree(K.x);
2622+ mpfree(K.y);
26112623
2624+ ecpubfree(Y);
2625+ }
26122626 return 0;
26132627 }
26142628
@@ -2617,8 +2631,8 @@ tlsSecInitc(TlsSec *sec, int cvers) · 2 unmodified lines
26172631 {
26182632 memset(sec, 0, sizeof(*sec));
26192633 sec->clientVers = cvers;
2620− put32(sec->crandom, time(nil));
2621− genrandom(sec->crandom+4, RandomSize-4);
2634+ // see the comment on tlsSecInits
2635+ genrandom(sec->crandom, RandomSize);
26222636 }
26232637
26242638 static Bytes*
@@ -2676,13 +2690,15 @@ tlsSecVers(TlsSec *sec, int v) · 51 unmodified lines
26762690 static int
26772691 setSecrets(TlsConnection *c, int isclient)
26782692 {
2679− uchar kd[MaxKeyData];
2693+ uchar kd[MaxKeyData], seed[2*RandomSize];
26802694 char *secrets;
26812695 int rv;
26822696
26832697 assert(c->nsecret <= sizeof(kd));
26842698 secrets = emalloc(2*c->nsecret);
26852699
2700+ memmove(seed, c->sec->srandom, RandomSize);
2701+ memmove(seed+RandomSize, c->sec->crandom, RandomSize);
26862702 /*
26872703 * generate secret keys from the master secret.
26882704 *
@@ -2691,7 +2707,7 @@ setSecrets(TlsConnection *c, int isclient) · 2 unmodified lines
26912707 * but it's all generated using the same function.
26922708 */
26932709 (*c->sec->prf)(kd, c->nsecret, c->sec->sec, MasterSecretSize, "key expansion",
2694− c->sec->srandom, RandomSize, c->sec->crandom, RandomSize);
2710+ seed, sizeof(seed));
26952711
26962712 enc64(secrets, 2*c->nsecret, kd, c->nsecret);
26972713 memset(kd, 0, c->nsecret);
@@ -2710,6 +2726,8 @@ setSecrets(TlsConnection *c, int isclient) · 12 unmodified lines
27102726 static void
27112727 setMasterSecret(TlsSec *sec, Bytes *pm)
27122728 {
2729+ uchar seed[2*RandomSize];
2730+
27132731 if(sec->psklen > 0){
27142732 Bytes *opm = pm;
27152733 uchar *p;
@@ -2726,8 +2744,10 @@ setMasterSecret(TlsSec *sec, Bytes *pm) · 10 unmodified lines
27262744 freebytes(opm);
27272745 }
27282746
2747+ memmove(seed, sec->crandom, RandomSize);
2748+ memmove(seed+RandomSize, sec->srandom, RandomSize);
27292749 (*sec->prf)(sec->sec, MasterSecretSize, pm->data, pm->len, "master secret",
2730− sec->crandom, RandomSize, sec->srandom, RandomSize);
2750+ seed, sizeof(seed));
27312751
27322752 memset(pm->data, 0, pm->len);
27332753 freebytes(pm);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t