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
66 int psklen;66 int psklen;
67 int clientVers; // version in ClientHello67 int clientVers; // version in ClientHello
68 uchar sec[MasterSecretSize]; // master secret68 uchar sec[MasterSecretSize]; // master secret
69 uchar crandom[RandomSize]; // client random
70 uchar srandom[RandomSize]; // server random69 uchar srandom[RandomSize]; // server random
70 uchar crandom[RandomSize]; // client random
71 71
72 Namedcurve *nc; // selected curve for ECDHE
72 // diffie hellman state73 // diffie hellman state
73 DHstate dh;74 DHstate dh;
74 struct {75 struct {
75 ECdomain dom;76 ECdomain dom;
76 ECpriv Q;77 ECpriv Q;
77 } ec;78 } ec;
79 uchar X[32];
78 80
79 // byte generation and handshake checksum81 // 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);
81 void (*setFinished)(TlsSec*, HandshakeHash, uchar*, int);83 void (*setFinished)(TlsSec*, HandshakeHash, uchar*, int);
82 int nfin;84 int nfin;
83};85};
@@ -107,7 +109,7 @@ typedef struct Msg{ · 23 unmodified lines
107 int tag;109 int tag;
108 union {110 union {
109 struct {111 struct {
110 int version;112 int version;
111 uchar random[RandomSize];113 uchar random[RandomSize];
112 Bytes* sid;114 Bytes* sid;
113 Ints* ciphers;115 Ints* ciphers;
@@ -115,7 +117,7 @@ typedef struct Msg{ · 1 unmodified line
115 Bytes* extensions;117 Bytes* extensions;
116 } clientHello;118 } clientHello;
117 struct {119 struct {
118 int version;120 int version;
119 uchar random[RandomSize];121 uchar random[RandomSize];
120 Bytes* sid;122 Bytes* sid;
121 int cipher;123 int cipher;
@@ -214,79 +216,36 @@ enum { · 92 unmodified lines
214 216
215// cipher suites217// cipher suites
216enum {218enum {
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,
227 TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0X000A,219 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,
239 TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0X0016,220 TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0X0016,
240 TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = 0x0017,221
241 TLS_DH_anon_WITH_RC4_128_MD5 = 0x0018,222 TLS_RSA_WITH_AES_128_CBC_SHA = 0X002F,
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,
249 TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0X0033,223 TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0X0033,
250 TLS_DH_anon_WITH_AES_128_CBC_SHA = 0X0034,
251 TLS_RSA_WITH_AES_256_CBC_SHA = 0X0035,224 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,
255 TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0X0039,225 TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0X0039,
256 TLS_DH_anon_WITH_AES_256_CBC_SHA = 0X003A,
257 TLS_RSA_WITH_AES_128_CBC_SHA256 = 0X003C,226 TLS_RSA_WITH_AES_128_CBC_SHA256 = 0X003C,
258 TLS_RSA_WITH_AES_256_CBC_SHA256 = 0X003D,227 TLS_RSA_WITH_AES_256_CBC_SHA256 = 0X003D,
259 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0X0067,228 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0X0067,
260 229
261 TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C,230 TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C,
262 TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D,
263 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E,231 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,
276 232
277 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013,233 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013,
278 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014,234 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014,
279 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027,
280 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023,235 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023,
236 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027,
281 237
282 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 = 0xCCA8,238 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B,
283 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = 0xCCA9,239 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F,
284 TLS_DHE_RSA_WITH_CHACHA20_POLY1305 = 0xCCAA,
285 240
286 GOOGLE_ECDHE_RSA_WITH_CHACHA20_POLY1305 = 0xCC13,241 GOOGLE_ECDHE_RSA_WITH_CHACHA20_POLY1305 = 0xCC13,
287 GOOGLE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = 0xCC14,242 GOOGLE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = 0xCC14,
288 GOOGLE_DHE_RSA_WITH_CHACHA20_POLY1305 = 0xCC15,243 GOOGLE_DHE_RSA_WITH_CHACHA20_POLY1305 = 0xCC15,
289 244
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
290 TLS_PSK_WITH_CHACHA20_POLY1305 = 0xCCAB,249 TLS_PSK_WITH_CHACHA20_POLY1305 = 0xCCAB,
291 TLS_PSK_WITH_AES_128_CBC_SHA256 = 0x00AE,250 TLS_PSK_WITH_AES_128_CBC_SHA256 = 0x00AE,
292 TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C,251 TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C,
@@ -300,6 +259,20 @@ enum { · 7 unmodified lines
300 CompressionMax259 CompressionMax
301};260};
302 261
262
263// curves
264enum {
265 X25519 = 0x001d,
266};
267
268// extensions
269enum {
270 Extsni = 0x0000,
271 Extec = 0x000a,
272 Extecp = 0x000b,
273 Extsigalgs = 0x000d,
274};
275
303static Algs cipherAlgs[] = {276static Algs cipherAlgs[] = {
304 // ECDHE-ECDSA277 // ECDHE-ECDSA
305 {"ccpoly96_aead", "clear", 2*(32+12), TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305},278 {"ccpoly96_aead", "clear", 2*(32+12), TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305},
@@ -343,6 +316,7 @@ static uchar compressors[] = { · 37 unmodified lines
343};316};
344 317
345static Namedcurve namedcurves[] = {318static Namedcurve namedcurves[] = {
319 X25519, nil,
346 0x0017, secp256r1,320 0x0017, secp256r1,
347 0x0018, secp384r1,321 0x0018, secp384r1,
348};322};
@@ -401,7 +375,7 @@ static int isPSK(int tlsid); · 52 unmodified lines
401static int isECDSA(int tlsid);375static int isECDSA(int tlsid);
402 376
403static int setAlgs(TlsConnection *c, int a);377static int setAlgs(TlsConnection *c, int a);
404static int okCipher(Ints *cv, int ispsk);378static int okCipher(Ints *cv, int ispsk, int canec);
405static int okCompression(Bytes *cv);379static int okCompression(Bytes *cv);
406static int initCiphers(void);380static int initCiphers(void);
407static Ints* makeciphers(int ispsk);381static Ints* makeciphers(int ispsk);
@@ -412,7 +386,7 @@ static void factotum_rsa_close(AuthRpc *rpc); · 4 unmodified lines
412 386
413static void tlsSecInits(TlsSec *sec, int cvers, uchar *crandom);387static void tlsSecInits(TlsSec *sec, int cvers, uchar *crandom);
414static int tlsSecRSAs(TlsSec *sec, Bytes *epm);388static int tlsSecRSAs(TlsSec *sec, Bytes *epm);
415static Bytes* tlsSecECDHEs1(TlsSec *sec, Namedcurve *nc);389static Bytes* tlsSecECDHEs1(TlsSec *sec);
416static int tlsSecECDHEs2(TlsSec *sec, Bytes *Yc);390static int tlsSecECDHEs2(TlsSec *sec, Bytes *Yc);
417static void tlsSecInitc(TlsSec *sec, int cvers);391static void tlsSecInitc(TlsSec *sec, int cvers);
418static Bytes* tlsSecRSAc(TlsSec *sec, uchar *cert, int ncert);392static Bytes* tlsSecRSAc(TlsSec *sec, uchar *cert, int ncert);
@@ -458,12 +432,13 @@ tlsServer(int fd, TLSconn *conn) · 39 unmodified lines
458{432{
459 char buf[8];433 char buf[8];
460 char dname[64];434 char dname[64];
435 uchar seed[2*RandomSize];
461 int n, data, ctl, hand;436 int n, data, ctl, hand;
462 TlsConnection *tls;437 TlsConnection *tls;
463 438
464 if(conn == nil)439 if(conn == nil)
465 return -1;440 return -1;
466 ctl = open("#a/tls/clone", ORDWR);441 ctl = open("#a/tls/clone", ORDWR|OCEXEC);
467 if(ctl < 0)442 if(ctl < 0)
468 return -1;443 return -1;
469 n = read(ctl, buf, sizeof(buf)-1);444 n = read(ctl, buf, sizeof(buf)-1);
@@ -474,7 +449,7 @@ tlsServer(int fd, TLSconn *conn) · 4 unmodified lines
474 buf[n] = 0;449 buf[n] = 0;
475 snprint(conn->dir, sizeof(conn->dir), "#a/tls/%s", buf);450 snprint(conn->dir, sizeof(conn->dir), "#a/tls/%s", buf);
476 snprint(dname, sizeof(dname), "#a/tls/%s/hand", buf);451 snprint(dname, sizeof(dname), "#a/tls/%s/hand", buf);
477 hand = open(dname, ORDWR);452 hand = open(dname, ORDWR|OCEXEC);
478 if(hand < 0){453 if(hand < 0){
479 close(ctl);454 close(ctl);
480 return -1;455 return -1;
@@ -502,13 +477,15 @@ tlsServer(int fd, TLSconn *conn) · 21 unmodified lines
502 conn->sessionID = nil;477 conn->sessionID = nil;
503 if(conn->sessionKey != nil478 if(conn->sessionKey != nil
504 && conn->sessionType != nil479 && 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);
506 tls->sec->prf(483 tls->sec->prf(
507 conn->sessionKey, conn->sessionKeylen,484 conn->sessionKey, conn->sessionKeylen,
508 tls->sec->sec, MasterSecretSize,485 tls->sec->sec, MasterSecretSize,
509 conn->sessionConst, 486 conn->sessionConst,
510 tls->sec->crandom, RandomSize,487 seed, sizeof(seed));
511 tls->sec->srandom, RandomSize);488 }
512 tlsConnectionFree(tls);489 tlsConnectionFree(tls);
513 close(fd);490 close(fd);
514 return data;491 return data;
@@ -530,7 +507,7 @@ tlsClientExtensions(TLSconn *conn, int *plen) · 15 unmodified lines
530 b = erealloc(b, m + 2+2+2+1+2+n);507 b = erealloc(b, m + 2+2+2+1+2+n);
531 p = b + m;508 p = b + m;
532 509
533 put16(p, 0), p += 2; /* Type: server_name */510 put16(p, Extsni), p += 2; /* Type: server_name */
534 put16(p, 2+1+2+n), p += 2; /* Length */511 put16(p, 2+1+2+n), p += 2; /* Length */
535 put16(p, 1+2+n), p += 2; /* Server Name list length */512 put16(p, 1+2+n), p += 2; /* Server Name list length */
536 *p++ = 0; /* Server Name Type: host_name */513 *p++ = 0; /* Server Name Type: host_name */
@@ -539,26 +516,26 @@ tlsClientExtensions(TLSconn *conn, int *plen) · 2 unmodified lines
539 p += n;516 p += n;
540 }517 }
541 518
542 // ECDHE519 // Elliptic Curves (also called Supported Groups)
543 if(ProtocolVersion >= TLS10Version){520 if(ProtocolVersion >= TLS10Version){
544 m = p - b;521 m = p - b;
545 b = erealloc(b, m + 2+2+2+nelem(namedcurves)*2 + 2+2+1+nelem(pointformats));522 b = erealloc(b, m + 2+2+2+nelem(namedcurves)*2 + 2+2+1+nelem(pointformats));
546 p = b + m;523 p = b + m;
547 524
548 n = nelem(namedcurves);525 n = nelem(namedcurves);
549 put16(p, 0x000a), p += 2; /* Type: elliptic_curves */526 put16(p, Extec), p += 2; /* Type: elliptic_curves / supported_groups */
550 put16(p, (n+1)*2), p += 2; /* Length */527 put16(p, (n+1)*2), p += 2; /* Length */
551 put16(p, n*2), p += 2; /* Elliptic Curves Length */528 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 */
553 put16(p, namedcurves[i].tlsid);530 put16(p, namedcurves[i].tlsid);
554 p += 2;531 p += 2;
555 }532 }
556 533
557 n = nelem(pointformats);534 n = nelem(pointformats);
558 put16(p, 0x000b), p += 2; /* Type: ec_point_formats */535 put16(p, Extecp), p += 2; /* Type: ec_point_formats */
559 put16(p, n+1), p += 2; /* Length */536 put16(p, n+1), p += 2; /* Length */
560 *p++ = n; /* EC point formats Length */537 *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 */
562 *p++ = pointformats[i];539 *p++ = pointformats[i];
563 }540 }
564 541
@@ -570,7 +547,7 @@ tlsClientExtensions(TLSconn *conn, int *plen) · 5 unmodified lines
570 b = erealloc(b, m + 2+2+2+n*2);547 b = erealloc(b, m + 2+2+2+n*2);
571 p = b + m;548 p = b + m;
572 549
573 put16(p, 0x000d), p += 2;550 put16(p, Extsigalgs), p += 2;
574 put16(p, n*2 + 2), p += 2;551 put16(p, n*2 + 2), p += 2;
575 put16(p, n*2), p += 2;552 put16(p, n*2), p += 2;
576 for(i=0; i < n; i++){553 for(i=0; i < n; i++){
@@ -590,13 +567,14 @@ tlsClient(int fd, TLSconn *conn) · 13 unmodified lines
590{567{
591 char buf[8];568 char buf[8];
592 char dname[64];569 char dname[64];
570 uchar seed[2*RandomSize];
593 int n, data, ctl, hand;571 int n, data, ctl, hand;
594 TlsConnection *tls;572 TlsConnection *tls;
595 uchar *ext;573 uchar *ext;
596 574
597 if(conn == nil)575 if(conn == nil)
598 return -1;576 return -1;
599 ctl = open("#a/tls/clone", ORDWR);577 ctl = open("#a/tls/clone", ORDWR|OCEXEC);
600 if(ctl < 0)578 if(ctl < 0)
601 return -1;579 return -1;
602 n = read(ctl, buf, sizeof(buf)-1);580 n = read(ctl, buf, sizeof(buf)-1);
@@ -607,7 +585,7 @@ tlsClient(int fd, TLSconn *conn) · 4 unmodified lines
607 buf[n] = 0;585 buf[n] = 0;
608 snprint(conn->dir, sizeof(conn->dir), "#a/tls/%s", buf);586 snprint(conn->dir, sizeof(conn->dir), "#a/tls/%s", buf);
609 snprint(dname, sizeof(dname), "#a/tls/%s/hand", buf);587 snprint(dname, sizeof(dname), "#a/tls/%s/hand", buf);
610 hand = open(dname, ORDWR);588 hand = open(dname, ORDWR|OCEXEC);
611 if(hand < 0){589 if(hand < 0){
612 close(ctl);590 close(ctl);
613 return -1;591 return -1;
@@ -645,13 +623,15 @@ tlsClient(int fd, TLSconn *conn) · 31 unmodified lines
645 conn->sessionID = nil;623 conn->sessionID = nil;
646 if(conn->sessionKey != nil624 if(conn->sessionKey != nil
647 && conn->sessionType != nil625 && 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);
649 tls->sec->prf(629 tls->sec->prf(
650 conn->sessionKey, conn->sessionKeylen,630 conn->sessionKey, conn->sessionKeylen,
651 tls->sec->sec, MasterSecretSize,631 tls->sec->sec, MasterSecretSize,
652 conn->sessionConst, 632 conn->sessionConst,
653 tls->sec->crandom, RandomSize,633 seed, sizeof(seed));
654 tls->sec->srandom, RandomSize);634 }
655 tlsConnectionFree(tls);635 tlsConnectionFree(tls);
656 close(fd);636 close(fd);
657 return data;637 return data;
@@ -669,6 +649,53 @@ countchain(PEMChain *p) · 11 unmodified lines
669 return i;649 return i;
670}650}
671 651
652static int
653checkClientExtensions(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;
694Short:
695 tlsError(c, EDecodeError, "clienthello extensions has invalid length");
696 return -1;
697}
698
672static TlsConnection *699static TlsConnection *
673tlsServer2(int ctl, int hand,700tlsServer2(int ctl, int hand,
674 uchar *cert, int certlen,701 uchar *cert, int certlen,
@@ -712,19 +739,6 @@ tlsServer2(int ctl, int hand, · 37 unmodified lines
712 tlsError(c, EInappropriateFallback, "inappropriate fallback");739 tlsError(c, EInappropriateFallback, "inappropriate fallback");
713 goto Err;740 goto Err;
714 }741 }
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
728 tlsSecInits(c->sec, m.u.clientHello.version, m.u.clientHello.random);742 tlsSecInits(c->sec, m.u.clientHello.version, m.u.clientHello.random);
729 tlsSecVers(c->sec, c->version);743 tlsSecVers(c->sec, c->version);
730 if(psklen > 0){744 if(psklen > 0){
@@ -744,6 +758,20 @@ tlsServer2(int ctl, int hand, · 13 unmodified lines
744 goto Err;758 goto Err;
745 }759 }
746 }760 }
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);
747 msgClear(&m);775 msgClear(&m);
748 776
749 m.tag = HServerHello;777 m.tag = HServerHello;
@@ -768,11 +796,9 @@ tlsServer2(int ctl, int hand, · 18 unmodified lines
768 }796 }
769 797
770 if(isECDHE(cipher)){798 if(isECDHE(cipher)){
771 Namedcurve *nc = &namedcurves[0]; /* secp256r1 */
772
773 m.tag = HServerKeyExchange;799 m.tag = HServerKeyExchange;
774 m.u.serverKeyExchange.curve = nc->tlsid;800 m.u.serverKeyExchange.curve = c->sec->nc->tlsid;
775 m.u.serverKeyExchange.dh_parameters = tlsSecECDHEs1(c->sec, nc);801 m.u.serverKeyExchange.dh_parameters = tlsSecECDHEs1(c->sec);
776 if(m.u.serverKeyExchange.dh_parameters == nil){802 if(m.u.serverKeyExchange.dh_parameters == nil){
777 tlsError(c, EInternalError, "can't set DH parameters");803 tlsError(c, EInternalError, "can't set DH parameters");
778 goto Err;804 goto Err;
@@ -893,7 +919,9 @@ tlsSecDHEc(TlsSec *sec, Bytes *p, Bytes *g, Bytes *Ys) · 114 unmodified lines
893 919
894 if(p == nil || g == nil || Ys == nil)920 if(p == nil || g == nil || Ys == nil)
895 return nil;921 return nil;
896 922 // reject dh primes that is susceptible to logjam
923 if(p->len <= 1024/8)
924 return nil;
897 Yc = nil;925 Yc = nil;
898 P = bytestomp(p);926 P = bytestomp(p);
899 G = bytestomp(g);927 G = bytestomp(g);
@@ -924,49 +952,65 @@ Out: · 24 unmodified lines
924static Bytes*952static Bytes*
925tlsSecECDHEc(TlsSec *sec, int curve, Bytes *Ys)953tlsSecECDHEc(TlsSec *sec, int curve, Bytes *Ys)
926{954{
955 static char zero[32] = {0};
927 ECdomain *dom = &sec->ec.dom;956 ECdomain *dom = &sec->ec.dom;
928 ECpriv *Q = &sec->ec.Q;957 ECpriv *Q = &sec->ec.Q;
929 Namedcurve *nc;
930 ECpub *pub;958 ECpub *pub;
931 ECpoint K;959 ECpoint K;
960 Namedcurve *nc;
932 Bytes *Yc;961 Bytes *Yc;
962 Bytes *Z;
933 int n;963 int n;
934 964
935 if(Ys == nil)965 if(Ys == nil)
936 return nil;966 return nil;
937 for(nc = namedcurves; nc != &namedcurves[nelem(namedcurves)]; nc++)
938 if(nc->tlsid == curve)
939 goto Found;
940 return nil;
941
942Found:
943 ecdominit(dom, nc->init);
944 pub = ecdecodepub(dom, Ys->data, Ys->len);
945 if(pub == nil)
946 return nil;
947 967
948 memset(Q, 0, sizeof(*Q));968 if(curve == X25519){
949 Q->a.x = mpnew(0);969 if(Ys->len != 32)
950 Q->a.y = mpnew(0);970 return nil;
951 Q->d = mpnew(0);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;
952 991
953 memset(&K, 0, sizeof(K));992 memset(Q, 0, sizeof(*Q));
954 K.x = mpnew(0);993 Q->x = mpnew(0);
955 K.y = mpnew(0);994 Q->y = mpnew(0);
995 Q->d = mpnew(0);
956 996
957 ecgen(dom, Q);997 memset(&K, 0, sizeof(K));
958 ecmul(dom, pub, Q->d, &K);998 K.x = mpnew(0);
999 K.y = mpnew(0);
959 1000
960 n = (mpsignif(dom->p)+7)/8;1001 ecgen(dom, Q);
961 setMasterSecret(sec, mptobytes(K.x, n));1002 ecmul(dom, pub, Q->d, &K);
962 Yc = newbytes(1 + 2*n);
963 Yc->len = ecencodepub(dom, (ECpub*)Q, Yc->data, Yc->len);
964 1003
965 mpfree(K.x);1004 n = (mpsignif(dom->p)+7)/8;
966 mpfree(K.y);1005 setMasterSecret(sec, mptobytes(K.x, n));
1006 Yc = newbytes(1 + 2*n);
1007 Yc->len = ecencodepub(dom, Q, Yc->data, Yc->len);
967 1008
968 ecpubfree(pub);1009 mpfree(K.x);
1010 mpfree(K.y);
969 1011
1012 ecpubfree(pub);
1013 }
970 return Yc;1014 return Yc;
971}1015}
972 1016
@@ -1049,7 +1093,6 @@ tlsClient2(int ctl, int hand, · 76 unmodified lines
1049 tlsError(c, EIllegalParameter, "invalid compression");1093 tlsError(c, EIllegalParameter, "invalid compression");
1050 goto Err;1094 goto Err;
1051 }1095 }
1052
1053 dhx = isDHE(cipher) || isECDHE(cipher);1096 dhx = isDHE(cipher) || isECDHE(cipher);
1054 if(!msgRecv(c, &m))1097 if(!msgRecv(c, &m))
1055 goto Err;1098 goto Err;
@@ -1790,8 +1833,7 @@ msgRecv(TlsConnection *c, Msg *m) · 734 unmodified lines
1790 goto Short;1833 goto Short;
1791Ok:1834Ok:
1792 if(c->trace)1835 if(c->trace)
1793 c->trace("recv %s", msgPrint((char*)c->sendp, 1836 c->trace("recv %s", msgPrint((char*)c->sendp, &c->buf[sizeof(c->buf)] - c->sendp, m));
1794 &c->buf[sizeof(c->buf)] - c->sendp, m));
1795 return 1;1837 return 1;
1796Short:1838Short:
1797 tlsError(c, EDecodeError, "handshake message (%d) has invalid length", type);1839 tlsError(c, EDecodeError, "handshake message (%d) has invalid length", type);
@@ -2042,8 +2084,8 @@ tlsConnectionFree(TlsConnection *c) · 244 unmodified lines
2042 2084
2043 dh_finish(&c->sec->dh, nil);2085 dh_finish(&c->sec->dh, nil);
2044 2086
2045 mpfree(c->sec->ec.Q.a.x);2087 mpfree(c->sec->ec.Q.x);
2046 mpfree(c->sec->ec.Q.a.y);2088 mpfree(c->sec->ec.Q.y);
2047 mpfree(c->sec->ec.Q.d);2089 mpfree(c->sec->ec.Q.d);
2048 ecdomfree(&c->sec->ec.dom);2090 ecdomfree(&c->sec->ec.dom);
2049 2091
@@ -2141,13 +2183,17 @@ setAlgs(TlsConnection *c, int a) · 91 unmodified lines
2141}2183}
2142 2184
2143static int2185static int
2144okCipher(Ints *cv, int ispsk)2186okCipher(Ints *cv, int ispsk, int canec)
2145{2187{
2146 int i, c;2188 int i, c;
2147 2189
2148 for(i = 0; i < nelem(cipherAlgs); i++) {2190 for(i = 0; i < nelem(cipherAlgs); i++) {
2149 c = cipherAlgs[i].tlsid;2191 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)
2151 continue;2197 continue;
2152 if(lookupid(cv, c) >= 0)2198 if(lookupid(cv, c) >= 0)
2153 return c;2199 return c;
@@ -2183,7 +2229,7 @@ initCiphers(void) · 29 unmodified lines
2183 unlock(&ciphLock);2229 unlock(&ciphLock);
2184 return nciphers;2230 return nciphers;
2185 }2231 }
2186 j = open("#a/tls/encalgs", OREAD);2232 j = open("#a/tls/encalgs", OREAD|OCEXEC);
2187 if(j < 0){2233 if(j < 0){
2188 werrstr("can't open #a/tls/encalgs: %r");2234 werrstr("can't open #a/tls/encalgs: %r");
2189 goto out;2235 goto out;
@@ -2207,7 +2253,7 @@ initCiphers(void) · 17 unmodified lines
2207 cipherAlgs[i].ok = ok;2253 cipherAlgs[i].ok = ok;
2208 }2254 }
2209 2255
2210 j = open("#a/tls/hashalgs", OREAD);2256 j = open("#a/tls/hashalgs", OREAD|OCEXEC);
2211 if(j < 0){2257 if(j < 0){
2212 werrstr("can't open #a/tls/hashalgs: %r");2258 werrstr("can't open #a/tls/hashalgs: %r");
2213 goto out;2259 goto out;
@@ -2266,7 +2312,7 @@ factotum_rsa_open(RSApub *rsapub) · 52 unmodified lines
2266 AuthRpc *rpc;2312 AuthRpc *rpc;
2267 2313
2268 // start talking to factotum2314 // start talking to factotum
2269 if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0)2315 if((afd = open("/mnt/factotum/rpc", ORDWR|OCEXEC)) < 0)
2270 return nil;2316 return nil;
2271 if((rpc = auth_allocrpc(afd)) == nil){2317 if((rpc = auth_allocrpc(afd)) == nil){
2272 close(afd);2318 close(afd);
@@ -2318,114 +2364,55 @@ factotum_rsa_close(AuthRpc *rpc) · 45 unmodified lines
2318}2364}
2319 2365
2320static void2366static void
2321tlsPmd5(uchar *buf, int nbuf, uchar *key, int nkey, uchar *label, int nlabel, uchar *seed0, int nseed0, uchar *seed1, int nseed1)2367tlsP(uchar *buf, int nbuf, uchar *key, int nkey, uchar *label, int nlabel, uchar *seed, int nseed,
2322{2368 DigestState* (*x)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*), int xlen)
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
2349static void
2350tlsPsha1(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
2378static void
2379p_sha256(uchar *buf, int nbuf, uchar *key, int nkey, uchar *label, int nlabel, uchar *seed, int nseed)
2380{2369{
2381 uchar ai[SHA2_256dlen], tmp[SHA2_256dlen];2370 uchar ai[SHA2_256dlen], tmp[SHA2_256dlen];
2382 SHAstate *s;2371 DigestState *s;
2383 int n;2372 int n;
2384 2373
2374 assert(sizeof(ai) <= xlen && sizeof(tmp) <= xlen);
2385 // generate a12375 // generate a1
2386 s = hmac_sha2_256(label, nlabel, key, nkey, nil, nil);2376 s = x(label, nlabel, key, nkey, nil, nil);
2387 hmac_sha2_256(seed, nseed, key, nkey, ai, s);2377 x(seed, nseed, key, nkey, ai, s);
2388 2378
2389 while(nbuf > 0) {2379 while(nbuf > 0) {
2390 s = hmac_sha2_256(ai, SHA2_256dlen, key, nkey, nil, nil);2380 s = x(ai, xlen, key, nkey, nil, nil);
2391 s = hmac_sha2_256(label, nlabel, key, nkey, nil, s);2381 s = x(label, nlabel, key, nkey, nil, s);
2392 hmac_sha2_256(seed, nseed, key, nkey, tmp, s);2382 x(seed, nseed, key, nkey, tmp, s);
2393 n = SHA2_256dlen;2383 n = xlen;
2394 if(n > nbuf)2384 if(n > nbuf)
2395 n = nbuf;2385 n = nbuf;
2396 memmove(buf, tmp, n);2386 memmove(buf, tmp, n);
2397 buf += n;2387 buf += n;
2398 nbuf -= n;2388 nbuf -= n;
2399 hmac_sha2_256(ai, SHA2_256dlen, key, nkey, tmp, nil);2389 x(ai, xlen, key, nkey, tmp, nil);
2400 memmove(ai, tmp, SHA2_256dlen);2390 memmove(ai, tmp, xlen);
2401 }2391 }
2402}2392}
2403 2393
2404// fill buf with md5(args)^sha1(args)2394// fill buf with md5(args)^sha1(args)
2405static void2395static void
2406tls10PRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed0, int nseed0, uchar *seed1, int nseed1)2396tls10PRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed, int nseed)
2407{2397{
2408 int nlabel = strlen(label);2398 int nlabel = strlen(label);
2409 int n = (nkey + 1) >> 1;2399 int n = (nkey + 1) >> 1;
2410 2400
2411 memset(buf, 0, nbuf);2401 tlsP(buf, nbuf, key, n, (uchar*)label, nlabel, seed, nseed,
2412 tlsPmd5(buf, nbuf, key, n, (uchar*)label, nlabel, seed0, nseed0, seed1, nseed1);2402 hmac_md5, MD5dlen);
2413 tlsPsha1(buf, nbuf, key+nkey-n, n, (uchar*)label, nlabel, seed0, nseed0, seed1, nseed1);2403 tlsP(buf, nbuf, key+nkey-n, n, (uchar*)label, nlabel, seed, nseed,
2404 hmac_sha1, SHA1dlen);
2414}2405}
2415 2406
2416static void2407static void
2417tls12PRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed0, int nseed0, uchar *seed1, int nseed1)2408tls12PRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed, int nseed)
2418{2409{
2419 uchar seed[2*RandomSize];2410 tlsP(buf, nbuf, key, nkey, (uchar*)label, strlen(label), seed, nseed,
2420 2411 hmac_sha2_256, SHA2_256dlen);
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);
2425}2412}
2426 2413
2427static void2414static void
2428sslPRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed0, int nseed0, uchar *seed1, int nseed1)2415sslPRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed, int nseed)
2429{2416{
2430 uchar sha1dig[SHA1dlen], md5dig[MD5dlen], tmp[26];2417 uchar sha1dig[SHA1dlen], md5dig[MD5dlen], tmp[26];
2431 DigestState *s;2418 DigestState *s;
@@ -2440,8 +2427,7 @@ sslPRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed0, in · 8 unmodified lines
2440 tmp[i] = 'A' - 1 + len;2427 tmp[i] = 'A' - 1 + len;
2441 s = sha1(tmp, len, nil, nil);2428 s = sha1(tmp, len, nil, nil);
2442 s = sha1(key, nkey, nil, s);2429 s = sha1(key, nkey, nil, s);
2443 s = sha1(seed0, nseed0, nil, s);2430 sha1(seed, nseed, sha1dig, s);
2444 sha1(seed1, nseed1, sha1dig, s);
2445 s = md5(key, nkey, nil, nil);2431 s = md5(key, nkey, nil, nil);
2446 md5(sha1dig, SHA1dlen, md5dig, s);2432 md5(sha1dig, SHA1dlen, md5dig, s);
2447 n = MD5dlen;2433 n = MD5dlen;
@@ -2491,18 +2477,18 @@ sslSetFinished(TlsSec *sec, HandshakeHash hsh, uchar *finished, int isclient) · 43 unmodified lines
2491static void2477static void
2492tls10SetFinished(TlsSec *sec, HandshakeHash hsh, uchar *finished, int isclient)2478tls10SetFinished(TlsSec *sec, HandshakeHash hsh, uchar *finished, int isclient)
2493{2479{
2494 uchar h0[MD5dlen], h1[SHA1dlen];2480 uchar h[MD5dlen+SHA1dlen];
2495 char *label;2481 char *label;
2496 2482
2497 // get current hash value, but allow further messages to be hashed in2483 // get current hash value, but allow further messages to be hashed in
2498 md5(nil, 0, h0, &hsh.md5);2484 md5(nil, 0, h, &hsh.md5);
2499 sha1(nil, 0, h1, &hsh.sha1);2485 sha1(nil, 0, h+MD5dlen, &hsh.sha1);
2500 2486
2501 if(isclient)2487 if(isclient)
2502 label = "client finished";2488 label = "client finished";
2503 else2489 else
2504 label = "server finished";2490 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));
2506}2492}
2507 2493
2508static void2494static void
@@ -2518,7 +2504,7 @@ tls12SetFinished(TlsSec *sec, HandshakeHash hsh, uchar *finished, int isclient) · 9 unmodified lines
2518 label = "client finished";2504 label = "client finished";
2519 else2505 else
2520 label = "server finished";2506 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);
2522}2508}
2523 2509
2524static void2510static void
@@ -2528,8 +2514,9 @@ tlsSecInits(TlsSec *sec, int cvers, uchar *crandom) · 3 unmodified lines
2528 sec->clientVers = cvers;2514 sec->clientVers = cvers;
2529 memmove(sec->crandom, crandom, RandomSize);2515 memmove(sec->crandom, crandom, RandomSize);
2530 2516
2531 put32(sec->srandom, time(nil));2517 // putting time()'s output to the first 4 bytes is no
2532 genrandom(sec->srandom+4, RandomSize-4);2518 // longer recommended and is not useful
2519 genrandom(sec->srandom, RandomSize);
2533}2520}
2534 2521
2535static int2522static int
@@ -2554,61 +2541,88 @@ tlsSecRSAs(TlsSec *sec, Bytes *epm) · 18 unmodified lines
2554}2541}
2555 2542
2556static Bytes*2543static Bytes*
2557tlsSecECDHEs1(TlsSec *sec, Namedcurve *nc)2544tlsSecECDHEs1(TlsSec *sec)
2558{2545{
2559 ECdomain *dom = &sec->ec.dom;2546 ECdomain *dom = &sec->ec.dom;
2560 ECpriv *Q = &sec->ec.Q;2547 ECpriv *Q = &sec->ec.Q;
2561 Bytes *par;2548 Bytes *par;
2562 int n;2549 int n;
2563 2550
2564 ecdominit(dom, nc->init);2551 if(sec->nc == nil)
2565 memset(Q, 0, sizeof(*Q));2552 return nil;
2566 Q->a.x = mpnew(0);2553 if(sec->nc->tlsid == X25519){
2567 Q->a.y = mpnew(0);2554 par = newbytes(1+2+1+32);
2568 Q->d = mpnew(0);2555 par->data[0] = 3;
2569 ecgen(dom, Q);2556 put16(par->data+1, X25519);
2570 n = 1 + 2*((mpsignif(dom->p)+7)/8);2557 par->data[3] = 32;
2571 par = newbytes(1+2+1+n);2558 curve25519_dh_new(sec->X, par->data+4);
2572 par->data[0] = 3;2559 }else{
2573 put16(par->data+1, nc->tlsid);2560 ecdominit(dom, sec->nc->init);
2574 n = ecencodepub(dom, (ECpub*)Q, par->data+4, par->len-4);2561 memset(Q, 0, sizeof(*Q));
2575 par->data[3] = n;2562 Q->x = mpnew(0);
2576 par->len = 1+2+1+n;2563 Q->y = mpnew(0);
2577 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 }
2578 return par;2574 return par;
2579}2575}
2580 2576
2581static int2577static int
2582tlsSecECDHEs2(TlsSec *sec, Bytes *Yc)2578tlsSecECDHEs2(TlsSec *sec, Bytes *Yc)
2583{2579{
2580 static char zero[32] = {0};
2584 ECdomain *dom = &sec->ec.dom;2581 ECdomain *dom = &sec->ec.dom;
2585 ECpriv *Q = &sec->ec.Q;2582 ECpriv *Q = &sec->ec.Q;
2586 ECpoint K;2583 ECpoint K;
2587 ECpub *Y;2584 ECpub *Y;
2585 Bytes *Z;
2588 2586
2589 if(Yc == nil){2587 if(Yc == nil){
2590 werrstr("no public key");2588 werrstr("no public key");
2591 return -1;2589 return -1;
2592 }2590 }
2593 2591
2594 if((Y = ecdecodepub(dom, Yc->data, Yc->len)) == nil){2592 if(sec->nc->tlsid == X25519){
2595 werrstr("bad public key");2593 if(Yc->len != 32){
2596 return -1;2594 werrstr("bad public key");
2597 }2595 return -1;
2598 2596 }
2599 memset(&K, 0, sizeof(K));2597 Z = newbytes(32);
2600 K.x = mpnew(0);2598 curve25519_dh_finish(sec->X, Yc->data, Z->data);
2601 K.y = mpnew(0);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 }
2602 2612
2603 ecmul(dom, Y, Q->d, &K);2613 memset(&K, 0, sizeof(K));
2614 K.x = mpnew(0);
2615 K.y = mpnew(0);
2604 2616
2605 setMasterSecret(sec, mptobytes(K.x, (mpsignif(dom->p)+7)/8));2617 ecmul(dom, Y, Q->d, &K);
2606 2618
2607 mpfree(K.x);2619 setMasterSecret(sec, mptobytes(K.x, (mpsignif(dom->p)+7)/8));
2608 mpfree(K.y);
2609 2620
2610 ecpubfree(Y);2621 mpfree(K.x);
2622 mpfree(K.y);
2611 2623
2624 ecpubfree(Y);
2625 }
2612 return 0;2626 return 0;
2613}2627}
2614 2628
@@ -2617,8 +2631,8 @@ tlsSecInitc(TlsSec *sec, int cvers) · 2 unmodified lines
2617{2631{
2618 memset(sec, 0, sizeof(*sec));2632 memset(sec, 0, sizeof(*sec));
2619 sec->clientVers = cvers;2633 sec->clientVers = cvers;
2620 put32(sec->crandom, time(nil));2634 // see the comment on tlsSecInits
2621 genrandom(sec->crandom+4, RandomSize-4);2635 genrandom(sec->crandom, RandomSize);
2622}2636}
2623 2637
2624static Bytes*2638static Bytes*
@@ -2676,13 +2690,15 @@ tlsSecVers(TlsSec *sec, int v) · 51 unmodified lines
2676static int2690static int
2677setSecrets(TlsConnection *c, int isclient)2691setSecrets(TlsConnection *c, int isclient)
2678{2692{
2679 uchar kd[MaxKeyData];2693 uchar kd[MaxKeyData], seed[2*RandomSize];
2680 char *secrets;2694 char *secrets;
2681 int rv;2695 int rv;
2682 2696
2683 assert(c->nsecret <= sizeof(kd));2697 assert(c->nsecret <= sizeof(kd));
2684 secrets = emalloc(2*c->nsecret);2698 secrets = emalloc(2*c->nsecret);
2685 2699
2700 memmove(seed, c->sec->srandom, RandomSize);
2701 memmove(seed+RandomSize, c->sec->crandom, RandomSize);
2686 /*2702 /*
2687 * generate secret keys from the master secret.2703 * generate secret keys from the master secret.
2688 *2704 *
@@ -2691,7 +2707,7 @@ setSecrets(TlsConnection *c, int isclient) · 2 unmodified lines
2691 * but it's all generated using the same function.2707 * but it's all generated using the same function.
2692 */2708 */
2693 (*c->sec->prf)(kd, c->nsecret, c->sec->sec, MasterSecretSize, "key expansion",2709 (*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));
2695 2711
2696 enc64(secrets, 2*c->nsecret, kd, c->nsecret);2712 enc64(secrets, 2*c->nsecret, kd, c->nsecret);
2697 memset(kd, 0, c->nsecret);2713 memset(kd, 0, c->nsecret);
@@ -2710,6 +2726,8 @@ setSecrets(TlsConnection *c, int isclient) · 12 unmodified lines
2710static void2726static void
2711setMasterSecret(TlsSec *sec, Bytes *pm)2727setMasterSecret(TlsSec *sec, Bytes *pm)
2712{2728{
2729 uchar seed[2*RandomSize];
2730
2713 if(sec->psklen > 0){2731 if(sec->psklen > 0){
2714 Bytes *opm = pm;2732 Bytes *opm = pm;
2715 uchar *p;2733 uchar *p;
@@ -2726,8 +2744,10 @@ setMasterSecret(TlsSec *sec, Bytes *pm) · 10 unmodified lines
2726 freebytes(opm);2744 freebytes(opm);
2727 }2745 }
2728 2746
2747 memmove(seed, sec->crandom, RandomSize);
2748 memmove(seed+RandomSize, sec->srandom, RandomSize);
2729 (*sec->prf)(sec->sec, MasterSecretSize, pm->data, pm->len, "master secret",2749 (*sec->prf)(sec->sec, MasterSecretSize, pm->data, pm->len, "master secret",
2730 sec->crandom, RandomSize, sec->srandom, RandomSize);2750 seed, sizeof(seed));
2731 2751
2732 memset(pm->data, 0, pm->len); 2752 memset(pm->data, 0, pm->len);
2733 freebytes(pm);2753 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