]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/port/devtls.c
pc kernel: fix wrong simd exception mask (fixes go bootstrap)
[plan9front.git] / sys / src / 9 / port / devtls.c
1 /*
2  *  devtls - record layer for transport layer security 1.2 and secure sockets layer 3.0
3  */
4 #include        "u.h"
5 #include        "../port/lib.h"
6 #include        "mem.h"
7 #include        "dat.h"
8 #include        "fns.h"
9 #include        "../port/error.h"
10
11 #include        <libsec.h>
12
13 typedef struct OneWay   OneWay;
14 typedef struct Secret   Secret;
15 typedef struct TlsRec   TlsRec;
16 typedef struct TlsErrs  TlsErrs;
17
18 enum {
19         Statlen=        1024,           /* max. length of status or stats message */
20         /* buffer limits */
21         MaxRecLen       = 1<<14,        /* max payload length of a record layer message */
22         MaxCipherRecLen = MaxRecLen + 2048,
23         RecHdrLen       = 5,
24         MaxMacLen       = SHA2_256dlen,
25
26         /* protocol versions we can accept */
27         SSL3Version     = 0x0300,
28         TLS10Version    = 0x0301,
29         TLS11Version    = 0x0302,
30         TLS12Version    = 0x0303,
31         MinProtoVersion = 0x0300,       /* limits on version we accept */
32         MaxProtoVersion = 0x03ff,
33
34         /* connection states */
35         SHandshake      = 1 << 0,       /* doing handshake */
36         SOpen           = 1 << 1,       /* application data can be sent */
37         SRClose         = 1 << 2,       /* remote side has closed down */
38         SLClose         = 1 << 3,       /* sent a close notify alert */
39         SAlert          = 1 << 5,       /* sending or sent a fatal alert */
40         SError          = 1 << 6,       /* some sort of error has occured */
41         SClosed         = 1 << 7,       /* it is all over */
42
43         /* record types */
44         RChangeCipherSpec = 20,
45         RAlert,
46         RHandshake,
47         RApplication,
48
49         SSL2ClientHello = 1,
50         HSSL2ClientHello = 9,  /* local convention;  see tlshand.c */
51
52         /* alerts */
53         ECloseNotify                    = 0,
54         EUnexpectedMessage      = 10,
55         EBadRecordMac           = 20,
56         EDecryptionFailed               = 21,
57         ERecordOverflow                 = 22,
58         EDecompressionFailure   = 30,
59         EHandshakeFailure               = 40,
60         ENoCertificate                  = 41,
61         EBadCertificate                 = 42,
62         EUnsupportedCertificate         = 43,
63         ECertificateRevoked             = 44,
64         ECertificateExpired             = 45,
65         ECertificateUnknown     = 46,
66         EIllegalParameter               = 47,
67         EUnknownCa                      = 48,
68         EAccessDenied           = 49,
69         EDecodeError                    = 50,
70         EDecryptError                   = 51,
71         EExportRestriction              = 60,
72         EProtocolVersion                = 70,
73         EInsufficientSecurity   = 71,
74         EInternalError                  = 80,
75         EUserCanceled                   = 90,
76         ENoRenegotiation                = 100,
77         EUnrecognizedName               = 112,
78
79         EMAX = 256
80 };
81
82 struct Secret
83 {
84         char            *encalg;        /* name of encryption alg */
85         char            *hashalg;       /* name of hash alg */
86
87         int             (*aead_enc)(Secret*, uchar*, int, uchar*, uchar*, int);
88         int             (*aead_dec)(Secret*, uchar*, int, uchar*, uchar*, int);
89
90         int             (*enc)(Secret*, uchar*, int);
91         int             (*dec)(Secret*, uchar*, int);
92         int             (*unpad)(uchar*, int, int);
93         DigestState*    (*mac)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
94
95         int             block;          /* encryption block len, 0 if none */
96         int             maclen;         /* # bytes of record mac / authentication tag */
97         int             recivlen;       /* # bytes of record iv for AEAD ciphers */
98         void            *enckey;
99         uchar           mackey[MaxMacLen];
100 };
101
102 struct OneWay
103 {
104         QLock           io;             /* locks io access */
105         QLock           seclock;        /* locks secret paramaters */
106         u64int          seq;
107         Secret          *sec;           /* cipher in use */
108         Secret          *new;           /* cipher waiting for enable */
109 };
110
111 struct TlsRec
112 {
113         Chan    *c;                             /* io channel */
114         int             ref;                            /* serialized by tdlock for atomic destroy */
115         int             version;                        /* version of the protocol we are speaking */
116         char            verset;                 /* version has been set */
117         char            opened;                 /* opened command every issued? */
118         char            err[ERRMAX];            /* error message to return to handshake requests */
119         vlong   handin;                 /* bytes communicated by the record layer */
120         vlong   handout;
121         vlong   datain;
122         vlong   dataout;
123
124         Lock            statelk;
125         int             state;
126         int             debug;
127
128         /*
129          * function to genrate authenticated data blob for different
130          * protocol versions
131          */
132         int             (*packAAD)(u64int, uchar*, uchar*);
133
134         /* input side -- protected by in.io */
135         OneWay          in;
136         Block           *processed;     /* next bunch of application data */
137         Block           *unprocessed;   /* data read from c but not parsed into records */
138
139         /* handshake queue */
140         Lock            hqlock;                 /* protects hqref, alloc & free of handq, hprocessed */
141         int             hqref;
142         Queue           *handq;         /* queue of handshake messages */
143         Block           *hprocessed;    /* remainder of last block read from handq */
144         QLock           hqread;         /* protects reads for hprocessed, handq */
145
146         /* output side */
147         OneWay          out;
148
149         /* protections */
150         char            *user;
151         int             perm;
152 };
153
154 struct TlsErrs{
155         int     err;
156         int     sslerr;
157         int     tlserr;
158         int     fatal;
159         char    *msg;
160 };
161
162 static TlsErrs tlserrs[] = {
163         {ECloseNotify,                  ECloseNotify,                   ECloseNotify,                   0,      "close notify"},
164         {EUnexpectedMessage,    EUnexpectedMessage,     EUnexpectedMessage,     1, "unexpected message"},
165         {EBadRecordMac,         EBadRecordMac,          EBadRecordMac,          1, "bad record mac"},
166         {EDecryptionFailed,             EIllegalParameter,              EDecryptionFailed,              1, "decryption failed"},
167         {ERecordOverflow,               EIllegalParameter,              ERecordOverflow,                1, "record too long"},
168         {EDecompressionFailure, EDecompressionFailure,  EDecompressionFailure,  1, "decompression failed"},
169         {EHandshakeFailure,             EHandshakeFailure,              EHandshakeFailure,              1, "could not negotiate acceptable security parameters"},
170         {ENoCertificate,                ENoCertificate,                 ECertificateUnknown,    1, "no appropriate certificate available"},
171         {EBadCertificate,               EBadCertificate,                EBadCertificate,                1, "corrupted or invalid certificate"},
172         {EUnsupportedCertificate,       EUnsupportedCertificate,        EUnsupportedCertificate,        1, "unsupported certificate type"},
173         {ECertificateRevoked,   ECertificateRevoked,            ECertificateRevoked,            1, "revoked certificate"},
174         {ECertificateExpired,           ECertificateExpired,            ECertificateExpired,            1, "expired certificate"},
175         {ECertificateUnknown,   ECertificateUnknown,    ECertificateUnknown,    1, "unacceptable certificate"},
176         {EIllegalParameter,             EIllegalParameter,              EIllegalParameter,              1, "illegal parameter"},
177         {EUnknownCa,                    EHandshakeFailure,              EUnknownCa,                     1, "unknown certificate authority"},
178         {EAccessDenied,         EHandshakeFailure,              EAccessDenied,          1, "access denied"},
179         {EDecodeError,                  EIllegalParameter,              EDecodeError,                   1, "error decoding message"},
180         {EDecryptError,                 EIllegalParameter,              EDecryptError,                  1, "error decrypting message"},
181         {EExportRestriction,            EHandshakeFailure,              EExportRestriction,             1, "export restriction violated"},
182         {EProtocolVersion,              EIllegalParameter,              EProtocolVersion,               1, "protocol version not supported"},
183         {EInsufficientSecurity, EHandshakeFailure,              EInsufficientSecurity,  1, "stronger security routines required"},
184         {EInternalError,                        EHandshakeFailure,              EInternalError,                 1, "internal error"},
185         {EUserCanceled,         ECloseNotify,                   EUserCanceled,                  0, "handshake canceled by user"},
186         {ENoRenegotiation,              EUnexpectedMessage,     ENoRenegotiation,               0, "no renegotiation"},
187 };
188
189 enum
190 {
191         /* max. open tls connections */
192         MaxTlsDevs      = 1024
193 };
194
195 static  Lock    tdlock;
196 static  int     tdhiwat;
197 static  int     maxtlsdevs = 128;
198 static  TlsRec  **tlsdevs;
199 static  char    **trnames;
200 static  char    *encalgs;
201 static  char    *hashalgs;
202
203 enum{
204         Qtopdir         = 1,    /* top level directory */
205         Qprotodir,
206         Qclonus,
207         Qencalgs,
208         Qhashalgs,
209         Qconvdir,               /* directory for a conversation */
210         Qdata,
211         Qctl,
212         Qhand,
213         Qstatus,
214         Qstats,
215 };
216
217 #define TYPE(x)         ((x).path & 0xf)
218 #define CONV(x)         (((x).path >> 5)&(MaxTlsDevs-1))
219 #define QID(c, y)       (((c)<<5) | (y))
220
221 static void     checkstate(TlsRec *, int, int);
222 static void     ensure(TlsRec*, Block**, int);
223 static void     consume(Block**, uchar*, int);
224 static Chan*    buftochan(char*);
225 static void     tlshangup(TlsRec*);
226 static void     tlsError(TlsRec*, char *);
227 static void     alertHand(TlsRec*, char *);
228 static TlsRec   *newtls(Chan *c);
229 static TlsRec   *mktlsrec(void);
230 static DigestState*sslmac_md5(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s);
231 static DigestState*sslmac_sha1(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s);
232 static DigestState*nomac(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s);
233 static int      sslPackAAD(u64int, uchar*, uchar*);
234 static int      tlsPackAAD(u64int, uchar*, uchar*);
235 static void     packMac(Secret*, uchar*, int, uchar*, int, uchar*);
236 static void     put64(uchar *p, u64int);
237 static void     put32(uchar *p, u32int);
238 static void     put24(uchar *p, int);
239 static void     put16(uchar *p, int);
240 static int      get16(uchar *p);
241 static void     tlsSetState(TlsRec *tr, int new, int old);
242 static void     rcvAlert(TlsRec *tr, int err);
243 static void     sendAlert(TlsRec *tr, int err);
244 static void     rcvError(TlsRec *tr, int err, char *msg, ...);
245 static int      rc4enc(Secret *sec, uchar *buf, int n);
246 static int      des3enc(Secret *sec, uchar *buf, int n);
247 static int      des3dec(Secret *sec, uchar *buf, int n);
248 static int      aesenc(Secret *sec, uchar *buf, int n);
249 static int      aesdec(Secret *sec, uchar *buf, int n);
250 static int      ccpoly_aead_enc(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data, int len);
251 static int      ccpoly_aead_dec(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data, int len);
252 static int      aesgcm_aead_enc(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data, int len);
253 static int      aesgcm_aead_dec(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data, int len);
254 static int      noenc(Secret *sec, uchar *buf, int n);
255 static int      sslunpad(uchar *buf, int n, int block);
256 static int      tlsunpad(uchar *buf, int n, int block);
257 static void     freeSec(Secret *sec);
258 static char     *tlsstate(int s);
259 static void     pdump(int, void*, char*);
260
261 #pragma varargck        argpos  rcvError        3
262
263 static char *tlsnames[] = {
264 [Qclonus]               "clone",
265 [Qencalgs]      "encalgs",
266 [Qhashalgs]     "hashalgs",
267 [Qdata]         "data",
268 [Qctl]          "ctl",
269 [Qhand]         "hand",
270 [Qstatus]               "status",
271 [Qstats]                "stats",
272 };
273
274 static int convdir[] = { Qctl, Qdata, Qhand, Qstatus, Qstats };
275
276 static int
277 tlsgen(Chan *c, char*, Dirtab *, int, int s, Dir *dp)
278 {
279         Qid q;
280         TlsRec *tr;
281         char *name, *nm;
282         int perm, t;
283
284         q.vers = 0;
285         q.type = QTFILE;
286
287         t = TYPE(c->qid);
288         switch(t) {
289         case Qtopdir:
290                 if(s == DEVDOTDOT){
291                         q.path = QID(0, Qtopdir);
292                         q.type = QTDIR;
293                         devdir(c, q, "#a", 0, eve, 0555, dp);
294                         return 1;
295                 }
296                 if(s > 0)
297                         return -1;
298                 q.path = QID(0, Qprotodir);
299                 q.type = QTDIR;
300                 devdir(c, q, "tls", 0, eve, 0555, dp);
301                 return 1;
302         case Qprotodir:
303                 if(s == DEVDOTDOT){
304                         q.path = QID(0, Qtopdir);
305                         q.type = QTDIR;
306                         devdir(c, q, ".", 0, eve, 0555, dp);
307                         return 1;
308                 }
309                 if(s < 3){
310                         switch(s) {
311                         default:
312                                 return -1;
313                         case 0:
314                                 q.path = QID(0, Qclonus);
315                                 break;
316                         case 1:
317                                 q.path = QID(0, Qencalgs);
318                                 break;
319                         case 2:
320                                 q.path = QID(0, Qhashalgs);
321                                 break;
322                         }
323                         perm = 0444;
324                         if(TYPE(q) == Qclonus)
325                                 perm = 0555;
326                         devdir(c, q, tlsnames[TYPE(q)], 0, eve, perm, dp);
327                         return 1;
328                 }
329                 s -= 3;
330                 if(s >= tdhiwat)
331                         return -1;
332                 q.path = QID(s, Qconvdir);
333                 q.type = QTDIR;
334                 lock(&tdlock);
335                 tr = tlsdevs[s];
336                 if(tr != nil)
337                         nm = tr->user;
338                 else
339                         nm = eve;
340                 if((name = trnames[s]) == nil){
341                         name = trnames[s] = smalloc(16);
342                         sprint(name, "%d", s);
343                 }
344                 devdir(c, q, name, 0, nm, 0555, dp);
345                 unlock(&tdlock);
346                 return 1;
347         case Qconvdir:
348                 if(s == DEVDOTDOT){
349                         q.path = QID(0, Qprotodir);
350                         q.type = QTDIR;
351                         devdir(c, q, "tls", 0, eve, 0555, dp);
352                         return 1;
353                 }
354                 if(s < 0 || s >= nelem(convdir))
355                         return -1;
356                 lock(&tdlock);
357                 tr = tlsdevs[CONV(c->qid)];
358                 if(tr != nil){
359                         nm = tr->user;
360                         perm = tr->perm;
361                 }else{
362                         perm = 0;
363                         nm = eve;
364                 }
365                 t = convdir[s];
366                 if(t == Qstatus || t == Qstats)
367                         perm &= 0444;
368                 q.path = QID(CONV(c->qid), t);
369                 devdir(c, q, tlsnames[t], 0, nm, perm, dp);
370                 unlock(&tdlock);
371                 return 1;
372         case Qclonus:
373         case Qencalgs:
374         case Qhashalgs:
375                 perm = 0444;
376                 if(t == Qclonus)
377                         perm = 0555;
378                 devdir(c, c->qid, tlsnames[t], 0, eve, perm, dp);
379                 return 1;
380         default:
381                 lock(&tdlock);
382                 tr = tlsdevs[CONV(c->qid)];
383                 if(tr != nil){
384                         nm = tr->user;
385                         perm = tr->perm;
386                 }else{
387                         perm = 0;
388                         nm = eve;
389                 }
390                 if(t == Qstatus || t == Qstats)
391                         perm &= 0444;
392                 devdir(c, c->qid, tlsnames[t], 0, nm, perm, dp);
393                 unlock(&tdlock);
394                 return 1;
395         }
396 }
397
398 static Chan*
399 tlsattach(char *spec)
400 {
401         Chan *c;
402
403         c = devattach('a', spec);
404         c->qid.path = QID(0, Qtopdir);
405         c->qid.type = QTDIR;
406         c->qid.vers = 0;
407         return c;
408 }
409
410 static Walkqid*
411 tlswalk(Chan *c, Chan *nc, char **name, int nname)
412 {
413         return devwalk(c, nc, name, nname, nil, 0, tlsgen);
414 }
415
416 static int
417 tlsstat(Chan *c, uchar *db, int n)
418 {
419         return devstat(c, db, n, nil, 0, tlsgen);
420 }
421
422 static Chan*
423 tlsopen(Chan *c, int omode)
424 {
425         TlsRec *tr, **pp;
426         int t;
427
428         t = TYPE(c->qid);
429         switch(t) {
430         default:
431                 panic("tlsopen");
432         case Qtopdir:
433         case Qprotodir:
434         case Qconvdir:
435                 if(omode != OREAD)
436                         error(Eperm);
437                 break;
438         case Qclonus:
439                 tr = newtls(c);
440                 if(tr == nil)
441                         error(Enodev);
442                 break;
443         case Qctl:
444         case Qdata:
445         case Qhand:
446         case Qstatus:
447         case Qstats:
448                 if((t == Qstatus || t == Qstats) && omode != OREAD)
449                         error(Eperm);
450                 if(waserror()) {
451                         unlock(&tdlock);
452                         nexterror();
453                 }
454                 lock(&tdlock);
455                 pp = &tlsdevs[CONV(c->qid)];
456                 tr = *pp;
457                 if(tr == nil)
458                         error("must open connection using clone");
459                 devpermcheck(tr->user, tr->perm, omode);
460                 if(t == Qhand){
461                         if(waserror()){
462                                 unlock(&tr->hqlock);
463                                 nexterror();
464                         }
465                         lock(&tr->hqlock);
466                         if(tr->handq != nil)
467                                 error(Einuse);
468                         tr->handq = qopen(2 * MaxCipherRecLen, 0, nil, nil);
469                         if(tr->handq == nil)
470                                 error("cannot allocate handshake queue");
471                         tr->hqref = 1;
472                         unlock(&tr->hqlock);
473                         poperror();
474                 }
475                 tr->ref++;
476                 unlock(&tdlock);
477                 poperror();
478                 break;
479         case Qencalgs:
480         case Qhashalgs:
481                 if(omode != OREAD)
482                         error(Eperm);
483                 break;
484         }
485         c->mode = openmode(omode);
486         c->flag |= COPEN;
487         c->offset = 0;
488         c->iounit = MaxRecLen;
489         return c;
490 }
491
492 static int
493 tlswstat(Chan *c, uchar *dp, int n)
494 {
495         Dir *d;
496         TlsRec *tr;
497         int rv;
498
499         d = nil;
500         if(waserror()){
501                 free(d);
502                 unlock(&tdlock);
503                 nexterror();
504         }
505
506         lock(&tdlock);
507         tr = tlsdevs[CONV(c->qid)];
508         if(tr == nil)
509                 error(Ebadusefd);
510         if(strcmp(tr->user, up->user) != 0)
511                 error(Eperm);
512
513         d = smalloc(n + sizeof *d);
514         rv = convM2D(dp, n, &d[0], (char*) &d[1]);
515         if(rv == 0)
516                 error(Eshortstat);
517         if(!emptystr(d->uid))
518                 kstrdup(&tr->user, d->uid);
519         if(d->mode != -1)
520                 tr->perm = d->mode;
521
522         free(d);
523         poperror();
524         unlock(&tdlock);
525
526         return rv;
527 }
528
529 static void
530 dechandq(TlsRec *tr)
531 {
532         lock(&tr->hqlock);
533         if(--tr->hqref == 0){
534                 if(tr->handq != nil){
535                         qfree(tr->handq);
536                         tr->handq = nil;
537                 }
538                 if(tr->hprocessed != nil){
539                         freeb(tr->hprocessed);
540                         tr->hprocessed = nil;
541                 }
542         }
543         unlock(&tr->hqlock);
544 }
545
546 static void
547 tlsclose(Chan *c)
548 {
549         TlsRec *tr;
550         int t;
551
552         t = TYPE(c->qid);
553         switch(t) {
554         case Qctl:
555         case Qdata:
556         case Qhand:
557         case Qstatus:
558         case Qstats:
559                 if((c->flag & COPEN) == 0)
560                         break;
561
562                 tr = tlsdevs[CONV(c->qid)];
563                 if(tr == nil)
564                         break;
565
566                 if(t == Qhand)
567                         dechandq(tr);
568
569                 lock(&tdlock);
570                 if(--tr->ref > 0) {
571                         unlock(&tdlock);
572                         return;
573                 }
574                 tlsdevs[CONV(c->qid)] = nil;
575                 unlock(&tdlock);
576
577                 if(tr->c != nil && !waserror()){
578                         checkstate(tr, 0, SOpen|SHandshake|SRClose);
579                         sendAlert(tr, ECloseNotify);
580                         poperror();
581                 }
582                 tlshangup(tr);
583                 if(tr->c != nil)
584                         cclose(tr->c);
585                 freeSec(tr->in.sec);
586                 freeSec(tr->in.new);
587                 freeSec(tr->out.sec);
588                 freeSec(tr->out.new);
589                 free(tr->user);
590                 free(tr);
591                 break;
592         }
593 }
594
595 /*
596  *  make sure we have at least 'n' bytes in list 'l'
597  */
598 static void
599 ensure(TlsRec *s, Block **l, int n)
600 {
601         int sofar, i;
602         Block *b, *bl;
603
604         sofar = 0;
605         for(b = *l; b; b = b->next){
606                 sofar += BLEN(b);
607                 if(sofar >= n)
608                         return;
609                 l = &b->next;
610         }
611
612         while(sofar < n){
613                 bl = devtab[s->c->type]->bread(s->c, MaxCipherRecLen + RecHdrLen, 0);
614                 if(bl == 0)
615                         error(Ehungup);
616                 *l = bl;
617                 i = 0;
618                 for(b = bl; b; b = b->next){
619                         i += BLEN(b);
620                         l = &b->next;
621                 }
622                 if(i == 0)
623                         error(Ehungup);
624                 sofar += i;
625         }
626 if(s->debug) pprint("ensure read %d\n", sofar);
627 }
628
629 /*
630  *  copy 'n' bytes from 'l' into 'p' and free
631  *  the bytes in 'l'
632  */
633 static void
634 consume(Block **l, uchar *p, int n)
635 {
636         Block *b;
637         int i;
638
639         for(; *l && n > 0; n -= i){
640                 b = *l;
641                 i = BLEN(b);
642                 if(i > n)
643                         i = n;
644                 memmove(p, b->rp, i);
645                 b->rp += i;
646                 p += i;
647                 if(BLEN(b) < 0)
648                         panic("consume");
649                 if(BLEN(b))
650                         break;
651                 *l = b->next;
652                 freeb(b);
653         }
654 }
655
656 /*
657  *  give back n bytes
658  */
659 static void
660 regurgitate(TlsRec *s, uchar *p, int n)
661 {
662         Block *b;
663
664         if(n <= 0)
665                 return;
666         b = s->unprocessed;
667         if(s->unprocessed == nil || b->rp - b->base < n) {
668                 b = allocb(n);
669                 memmove(b->wp, p, n);
670                 b->wp += n;
671                 b->next = s->unprocessed;
672                 s->unprocessed = b;
673         } else {
674                 b->rp -= n;
675                 memmove(b->rp, p, n);
676         }
677 }
678
679 /*
680  *  remove at most n bytes from the queue
681  */
682 static Block*
683 qgrab(Block **l, int n)
684 {
685         Block *bb, *b;
686         int i;
687
688         b = *l;
689         if(BLEN(b) == n){
690                 *l = b->next;
691                 b->next = nil;
692                 return b;
693         }
694
695         i = 0;
696         for(bb = b; bb != nil && i < n; bb = bb->next)
697                 i += BLEN(bb);
698         if(i > n)
699                 i = n;
700
701         bb = allocb(i);
702         consume(l, bb->wp, i);
703         bb->wp += i;
704         return bb;
705 }
706
707 static void
708 tlsclosed(TlsRec *tr, int new)
709 {
710         lock(&tr->statelk);
711         if(tr->state == SOpen || tr->state == SHandshake)
712                 tr->state = new;
713         else if((new | tr->state) == (SRClose|SLClose))
714                 tr->state = SClosed;
715         unlock(&tr->statelk);
716         alertHand(tr, "close notify");
717 }
718
719 /*
720  *  read and process one tls record layer message
721  *  must be called with tr->in.io held
722  *  We can't let Eintrs lose data, since doing so will get
723  *  us out of sync with the sender and break the reliablity
724  *  of the channel.  Eintr only happens during the reads in
725  *  consume.  Therefore we put back any bytes consumed before
726  *  the last call to ensure.
727  */
728 static void
729 tlsrecread(TlsRec *tr)
730 {
731         OneWay *volatile in;
732         Block *volatile b;
733         uchar *p, aad[8+RecHdrLen], header[RecHdrLen], hmac[MaxMacLen];
734         int volatile nconsumed;
735         int len, type, ver, unpad_len, aadlen, ivlen;
736         Secret *sec;
737
738         nconsumed = 0;
739         if(waserror()){
740                 if(strcmp(up->errstr, Eintr) == 0 && !waserror()){
741                         regurgitate(tr, header, nconsumed);
742                         poperror();
743                 }else
744                         tlsError(tr, "channel error");
745                 nexterror();
746         }
747         ensure(tr, &tr->unprocessed, RecHdrLen);
748         consume(&tr->unprocessed, header, RecHdrLen);
749 if(tr->debug)pprint("consumed %d header\n", RecHdrLen);
750         nconsumed = RecHdrLen;
751
752         if((tr->handin == 0) && (header[0] & 0x80)){
753                 /* Cope with an SSL3 ClientHello expressed in SSL2 record format.
754                         This is sent by some clients that we must interoperate
755                         with, such as Java's JSSE and Microsoft's Internet Explorer. */
756                 len = (get16(header) & ~0x8000) - 3;
757                 type = header[2];
758                 ver = get16(header + 3);
759                 if(type != SSL2ClientHello || len < 22)
760                         rcvError(tr, EProtocolVersion, "invalid initial SSL2-like message");
761         }else{  /* normal SSL3 record format */
762                 type = header[0];
763                 ver = get16(header+1);
764                 len = get16(header+3);
765         }
766         if(ver != tr->version && (tr->verset || ver < MinProtoVersion || ver > MaxProtoVersion))
767                 rcvError(tr, EProtocolVersion, "devtls expected ver=%x%s, saw (len=%d) type=%x ver=%x '%.12s'",
768                         tr->version, tr->verset?"/set":"", len, type, ver, (char*)header);
769         if(len > MaxCipherRecLen || len < 0)
770                 rcvError(tr, ERecordOverflow, "record message too long %d", len);
771         ensure(tr, &tr->unprocessed, len);
772         nconsumed = 0;
773         poperror();
774
775         /*
776          * If an Eintr happens after this, we'll get out of sync.
777          * Make sure nothing we call can sleep.
778          * Errors are ok, as they kill the connection.
779          * Luckily, allocb won't sleep, it'll just error out.
780          */
781         b = nil;
782         if(waserror()){
783                 if(b != nil)
784                         freeb(b);
785                 tlsError(tr, "channel error");
786                 nexterror();
787         }
788         b = qgrab(&tr->unprocessed, len);
789 if(tr->debug) pprint("consumed unprocessed %d\n", len);
790
791         in = &tr->in;
792         if(waserror()){
793                 qunlock(&in->seclock);
794                 nexterror();
795         }
796         qlock(&in->seclock);
797         p = b->rp;
798         sec = in->sec;
799         if(sec != nil) {
800                 /* to avoid Canvel-Hiltgen-Vaudenay-Vuagnoux attack, all errors here
801                         should look alike, including timing of the response. */
802                 if(sec->aead_dec != nil)
803                         unpad_len = len;
804                 else {
805                         unpad_len = (*sec->dec)(sec, p, len);
806 if(tr->debug) pprint("decrypted %d\n", unpad_len);
807 if(tr->debug) pdump(unpad_len, p, "decrypted:");
808                 }
809
810                 ivlen = sec->recivlen;
811                 if(tr->version >= TLS11Version){
812                         if(ivlen == 0)
813                                 ivlen = sec->block;
814                 }
815                 len -= ivlen;
816                 if(len < 0)
817                         rcvError(tr, EDecodeError, "runt record message");
818                 unpad_len -= ivlen;
819                 p += ivlen;
820
821                 if(unpad_len >= sec->maclen)
822                         len = unpad_len - sec->maclen;
823
824                 /* update length */
825                 put16(header+3, len);
826                 aadlen = (*tr->packAAD)(in->seq++, header, aad);
827                 if(sec->aead_dec != nil) {
828                         len = (*sec->aead_dec)(sec, aad, aadlen, p - ivlen, p, unpad_len);
829                         if(len < 0)
830                                 rcvError(tr, EBadRecordMac, "record mac mismatch");
831                 } else {
832                         packMac(sec, aad, aadlen, p, len, hmac);
833                         if(unpad_len < sec->maclen)
834                                 rcvError(tr, EBadRecordMac, "short record mac");
835                         if(tsmemcmp(hmac, p + len, sec->maclen) != 0)
836                                 rcvError(tr, EBadRecordMac, "record mac mismatch");
837                 }
838                 b->rp = p;
839                 b->wp = p+len;
840         }
841         qunlock(&in->seclock);
842         poperror();
843         if(len < 0)
844                 rcvError(tr, EDecodeError, "runt record message");
845
846         switch(type) {
847         default:
848                 rcvError(tr, EIllegalParameter, "invalid record message %#x", type);
849                 break;
850         case RChangeCipherSpec:
851                 if(len != 1 || p[0] != 1)
852                         rcvError(tr, EDecodeError, "invalid change cipher spec");
853                 qlock(&in->seclock);
854                 if(in->new == nil){
855                         qunlock(&in->seclock);
856                         rcvError(tr, EUnexpectedMessage, "unexpected change cipher spec");
857                 }
858                 freeSec(in->sec);
859                 in->sec = in->new;
860                 in->new = nil;
861                 in->seq = 0;
862                 qunlock(&in->seclock);
863                 break;
864         case RAlert:
865                 if(len != 2)
866                         rcvError(tr, EDecodeError, "invalid alert");
867                 if(p[0] == 2)
868                         rcvAlert(tr, p[1]);
869                 if(p[0] != 1)
870                         rcvError(tr, EIllegalParameter, "invalid alert fatal code");
871
872                 /*
873                  * propagate non-fatal alerts to handshaker
874                  */
875                 switch(p[1]){
876                 case ECloseNotify:
877                         tlsclosed(tr, SRClose);
878                         if(tr->opened)
879                                 error("tls hungup");
880                         error("close notify");
881                         break;
882                 case ENoRenegotiation:
883                         alertHand(tr, "no renegotiation");
884                         break;
885                 case EUserCanceled:
886                         alertHand(tr, "handshake canceled by user");
887                         break;
888                 case EUnrecognizedName:
889                         /* happens in response to SNI, can be ignored. */
890                         break;
891                 default:
892                         rcvError(tr, EIllegalParameter, "invalid alert code");
893                 }
894                 break;
895         case RHandshake:
896                 /*
897                  * don't worry about dropping the block
898                  * qbwrite always queues even if flow controlled and interrupted.
899                  *
900                  * if there isn't any handshaker, ignore the request,
901                  * but notify the other side we are doing so.
902                  */
903                 lock(&tr->hqlock);
904                 if(tr->handq != nil){
905                         tr->hqref++;
906                         unlock(&tr->hqlock);
907                         if(waserror()){
908                                 dechandq(tr);
909                                 nexterror();
910                         }
911                         b = padblock(b, 1);
912                         *b->rp = RHandshake;
913                         qbwrite(tr->handq, b);
914                         b = nil;
915                         poperror();
916                         dechandq(tr);
917                 }else{
918                         unlock(&tr->hqlock);
919                         if(tr->verset && tr->version != SSL3Version && !waserror()){
920                                 sendAlert(tr, ENoRenegotiation);
921                                 poperror();
922                         }
923                 }
924                 break;
925         case SSL2ClientHello:
926                 lock(&tr->hqlock);
927                 if(tr->handq != nil){
928                         tr->hqref++;
929                         unlock(&tr->hqlock);
930                         if(waserror()){
931                                 dechandq(tr);
932                                 nexterror();
933                         }
934                         /* Pass the SSL2 format data, so that the handshake code can compute
935                                 the correct checksums.  HSSL2ClientHello = HandshakeType 9 is
936                                 unused in RFC2246. */
937                         b = padblock(b, 8);
938                         b->rp[0] = RHandshake;
939                         b->rp[1] = HSSL2ClientHello;
940                         put24(&b->rp[2], len+3);
941                         b->rp[5] = SSL2ClientHello;
942                         put16(&b->rp[6], ver);
943                         qbwrite(tr->handq, b);
944                         b = nil;
945                         poperror();
946                         dechandq(tr);
947                 }else{
948                         unlock(&tr->hqlock);
949                         if(tr->verset && tr->version != SSL3Version && !waserror()){
950                                 sendAlert(tr, ENoRenegotiation);
951                                 poperror();
952                         }
953                 }
954                 break;
955         case RApplication:
956                 if(!tr->opened)
957                         rcvError(tr, EUnexpectedMessage, "application message received before handshake completed");
958                 if(BLEN(b) > 0){
959                         tr->processed = b;
960                         b = nil;
961                 }
962                 break;
963         }
964         if(b != nil)
965                 freeb(b);
966         poperror();
967 }
968
969 /*
970  * got a fatal alert message
971  */
972 static void
973 rcvAlert(TlsRec *tr, int err)
974 {
975         char *s;
976         int i;
977
978         s = "unknown error";
979         for(i=0; i < nelem(tlserrs); i++){
980                 if(tlserrs[i].err == err){
981                         s = tlserrs[i].msg;
982                         break;
983                 }
984         }
985 if(tr->debug) pprint("rcvAlert: %s\n", s);
986
987         tlsError(tr, s);
988         if(!tr->opened)
989                 error(s);
990         error("tls error");
991 }
992
993 /*
994  * found an error while decoding the input stream
995  */
996 static void
997 rcvError(TlsRec *tr, int err, char *fmt, ...)
998 {
999         char msg[ERRMAX];
1000         va_list arg;
1001
1002         va_start(arg, fmt);
1003         vseprint(msg, msg+sizeof(msg), fmt, arg);
1004         va_end(arg);
1005 if(tr->debug) pprint("rcvError: %s\n", msg);
1006
1007         sendAlert(tr, err);
1008
1009         if(!tr->opened)
1010                 error(msg);
1011         error("tls error");
1012 }
1013
1014 /*
1015  * make sure the next hand operation returns with a 'msg' error
1016  */
1017 static void
1018 alertHand(TlsRec *tr, char *msg)
1019 {
1020         Block *b;
1021         int n;
1022
1023         lock(&tr->hqlock);
1024         if(tr->handq == nil){
1025                 unlock(&tr->hqlock);
1026                 return;
1027         }
1028         tr->hqref++;
1029         unlock(&tr->hqlock);
1030
1031         n = strlen(msg);
1032         if(waserror()){
1033                 dechandq(tr);
1034                 nexterror();
1035         }
1036         b = allocb(n + 2);
1037         *b->wp++ = RAlert;
1038         memmove(b->wp, msg, n + 1);
1039         b->wp += n + 1;
1040
1041         qbwrite(tr->handq, b);
1042
1043         poperror();
1044         dechandq(tr);
1045 }
1046
1047 static void
1048 checkstate(TlsRec *tr, int ishand, int ok)
1049 {
1050         int state;
1051
1052         lock(&tr->statelk);
1053         state = tr->state;
1054         unlock(&tr->statelk);
1055         if(state & ok)
1056                 return;
1057         switch(state){
1058         case SHandshake:
1059         case SOpen:
1060                 break;
1061         case SError:
1062         case SAlert:
1063                 if(ishand)
1064                         error(tr->err);
1065                 error("tls error");
1066         case SRClose:
1067         case SLClose:
1068         case SClosed:
1069                 error("tls hungup");
1070         }
1071         error("tls improperly configured");
1072 }
1073
1074 static Block*
1075 tlsbread(Chan *c, long n, ulong offset)
1076 {
1077         int ty;
1078         Block *b;
1079         TlsRec *volatile tr;
1080
1081         ty = TYPE(c->qid);
1082         switch(ty) {
1083         default:
1084                 return devbread(c, n, offset);
1085         case Qhand:
1086         case Qdata:
1087                 break;
1088         }
1089
1090         tr = tlsdevs[CONV(c->qid)];
1091         if(tr == nil)
1092                 panic("tlsbread");
1093
1094         if(waserror()){
1095                 qunlock(&tr->in.io);
1096                 nexterror();
1097         }
1098         qlock(&tr->in.io);
1099         if(ty == Qdata){
1100                 checkstate(tr, 0, SOpen);
1101                 while(tr->processed == nil)
1102                         tlsrecread(tr);
1103
1104                 /* return at most what was asked for */
1105                 b = qgrab(&tr->processed, n);
1106 if(tr->debug) pprint("consumed processed %zd\n", BLEN(b));
1107 if(tr->debug) pdump(BLEN(b), b->rp, "consumed:");
1108                 qunlock(&tr->in.io);
1109                 poperror();
1110                 tr->datain += BLEN(b);
1111         }else{
1112                 checkstate(tr, 1, SOpen|SHandshake|SLClose);
1113
1114                 /*
1115                  * it's ok to look at state without the lock
1116                  * since it only protects reading records,
1117                  * and we have that tr->in.io held.
1118                  */
1119                 while(!tr->opened && tr->hprocessed == nil && !qcanread(tr->handq))
1120                         tlsrecread(tr);
1121
1122                 qunlock(&tr->in.io);
1123                 poperror();
1124
1125                 if(waserror()){
1126                         qunlock(&tr->hqread);
1127                         nexterror();
1128                 }
1129                 qlock(&tr->hqread);
1130                 if(tr->hprocessed == nil){
1131                         b = qbread(tr->handq, MaxRecLen + 1);
1132                         if(*b->rp++ == RAlert){
1133                                 kstrcpy(up->errstr, (char*)b->rp, ERRMAX);
1134                                 freeb(b);
1135                                 nexterror();
1136                         }
1137                         tr->hprocessed = b;
1138                 }
1139                 b = qgrab(&tr->hprocessed, n);
1140                 poperror();
1141                 qunlock(&tr->hqread);
1142                 tr->handin += BLEN(b);
1143         }
1144
1145         return b;
1146 }
1147
1148 static long
1149 tlsread(Chan *c, void *a, long n, vlong off)
1150 {
1151         Block *volatile b;
1152         Block *nb;
1153         uchar *va;
1154         int i, ty;
1155         char *buf, *s, *e;
1156         ulong offset = off;
1157         TlsRec * tr;
1158
1159         if(c->qid.type & QTDIR)
1160                 return devdirread(c, a, n, 0, 0, tlsgen);
1161
1162         tr = tlsdevs[CONV(c->qid)];
1163         ty = TYPE(c->qid);
1164         switch(ty) {
1165         default:
1166                 error(Ebadusefd);
1167         case Qstatus:
1168                 buf = smalloc(Statlen);
1169                 qlock(&tr->in.seclock);
1170                 qlock(&tr->out.seclock);
1171                 s = buf;
1172                 e = buf + Statlen;
1173                 s = seprint(s, e, "State: %s\n", tlsstate(tr->state));
1174                 s = seprint(s, e, "Version: %#x\n", tr->version);
1175                 if(tr->in.sec != nil)
1176                         s = seprint(s, e, "EncIn: %s\nHashIn: %s\n", tr->in.sec->encalg, tr->in.sec->hashalg);
1177                 if(tr->in.new != nil)
1178                         s = seprint(s, e, "NewEncIn: %s\nNewHashIn: %s\n", tr->in.new->encalg, tr->in.new->hashalg);
1179                 if(tr->out.sec != nil)
1180                         s = seprint(s, e, "EncOut: %s\nHashOut: %s\n", tr->out.sec->encalg, tr->out.sec->hashalg);
1181                 if(tr->out.new != nil)
1182                         s = seprint(s, e, "NewEncOut: %s\nNewHashOut: %s\n", tr->out.new->encalg, tr->out.new->hashalg);
1183                 if(tr->c != nil)
1184                         seprint(s, e, "Chan: %s\n", chanpath(tr->c));
1185                 qunlock(&tr->in.seclock);
1186                 qunlock(&tr->out.seclock);
1187                 n = readstr(offset, a, n, buf);
1188                 free(buf);
1189                 return n;
1190         case Qstats:
1191                 buf = smalloc(Statlen);
1192                 s = buf;
1193                 e = buf + Statlen;
1194                 s = seprint(s, e, "DataIn: %lld\n", tr->datain);
1195                 s = seprint(s, e, "DataOut: %lld\n", tr->dataout);
1196                 s = seprint(s, e, "HandIn: %lld\n", tr->handin);
1197                 seprint(s, e, "HandOut: %lld\n", tr->handout);
1198                 n = readstr(offset, a, n, buf);
1199                 free(buf);
1200                 return n;
1201         case Qctl:
1202                 buf = smalloc(Statlen);
1203                 snprint(buf, Statlen, "%llud", CONV(c->qid));
1204                 n = readstr(offset, a, n, buf);
1205                 free(buf);
1206                 return n;
1207         case Qdata:
1208         case Qhand:
1209                 b = tlsbread(c, n, offset);
1210                 break;
1211         case Qencalgs:
1212                 return readstr(offset, a, n, encalgs);
1213         case Qhashalgs:
1214                 return readstr(offset, a, n, hashalgs);
1215         }
1216
1217         if(waserror()){
1218                 freeblist(b);
1219                 nexterror();
1220         }
1221
1222         n = 0;
1223         va = a;
1224         for(nb = b; nb; nb = nb->next){
1225                 i = BLEN(nb);
1226                 memmove(va+n, nb->rp, i);
1227                 n += i;
1228         }
1229
1230         freeblist(b);
1231         poperror();
1232
1233         return n;
1234 }
1235
1236 /*
1237  *  write a block in tls records
1238  */
1239 static void
1240 tlsrecwrite(TlsRec *tr, int type, Block *b)
1241 {
1242         Block *volatile bb;
1243         Block *nb;
1244         uchar *p, aad[8+RecHdrLen];
1245         OneWay *volatile out;
1246         int n, ivlen, maclen, aadlen, pad, ok;
1247         Secret *sec;
1248
1249         out = &tr->out;
1250         bb = b;
1251         if(waserror()){
1252                 qunlock(&out->io);
1253                 if(bb != nil)
1254                         freeb(bb);
1255                 nexterror();
1256         }
1257         qlock(&out->io);
1258 if(tr->debug)pprint("send %zd\n", BLEN(b));
1259 if(tr->debug)pdump(BLEN(b), b->rp, "sent:");
1260
1261
1262         ok = SHandshake|SOpen|SRClose;
1263         if(type == RAlert)
1264                 ok |= SAlert;
1265         while(bb != nil){
1266                 checkstate(tr, type != RApplication, ok);
1267
1268                 /*
1269                  * get at most one maximal record's input,
1270                  * with padding on the front for header and
1271                  * back for mac and maximal block padding.
1272                  */
1273                 if(waserror()){
1274                         qunlock(&out->seclock);
1275                         nexterror();
1276                 }
1277                 qlock(&out->seclock);
1278                 maclen = 0;
1279                 pad = 0;
1280                 ivlen = 0;
1281                 sec = out->sec;
1282                 if(sec != nil){
1283                         maclen = sec->maclen;
1284                         pad = maclen + sec->block;
1285                         ivlen = sec->recivlen;
1286                         if(tr->version >= TLS11Version){
1287                                 if(ivlen == 0)
1288                                         ivlen = sec->block;
1289                         }
1290                 }
1291                 n = BLEN(bb);
1292                 if(n > MaxRecLen){
1293                         n = MaxRecLen;
1294                         nb = allocb(RecHdrLen + ivlen + n + pad);
1295                         memmove(nb->wp + RecHdrLen + ivlen, bb->rp, n);
1296                         bb->rp += n;
1297                 }else{
1298                         /*
1299                          * carefully reuse bb so it will get freed if we're out of memory
1300                          */
1301                         bb = padblock(bb, RecHdrLen + ivlen);
1302                         if(pad)
1303                                 nb = padblock(bb, -pad);
1304                         else
1305                                 nb = bb;
1306                         bb = nil;
1307                 }
1308
1309                 p = nb->rp;
1310                 p[0] = type;
1311                 put16(p+1, tr->version);
1312                 put16(p+3, n);
1313
1314                 if(sec != nil){
1315                         aadlen = (*tr->packAAD)(out->seq++, p, aad);
1316                         if(sec->aead_enc != nil)
1317                                 n = (*sec->aead_enc)(sec, aad, aadlen, p + RecHdrLen, p + RecHdrLen + ivlen, n) + ivlen;
1318                         else {
1319                                 if(ivlen > 0)
1320                                         prng(p + RecHdrLen, ivlen);
1321                                 packMac(sec, aad, aadlen, p + RecHdrLen + ivlen, n, p + RecHdrLen + ivlen + n);
1322                                 n = (*sec->enc)(sec, p + RecHdrLen, ivlen + n + maclen);
1323                         }
1324                         nb->wp = p + RecHdrLen + n;
1325
1326                         /* update length */
1327                         put16(p+3, n);
1328                 }
1329                 if(type == RChangeCipherSpec){
1330                         if(out->new == nil)
1331                                 error("change cipher without a new cipher");
1332                         freeSec(out->sec);
1333                         out->sec = out->new;
1334                         out->new = nil;
1335                         out->seq = 0;
1336                 }
1337                 qunlock(&out->seclock);
1338                 poperror();
1339
1340                 /*
1341                  * if bwrite error's, we assume the block is queued.
1342                  * if not, we're out of sync with the receiver and will not recover.
1343                  */
1344                 if(waserror()){
1345                         if(strcmp(up->errstr, "interrupted") != 0)
1346                                 tlsError(tr, "channel error");
1347                         nexterror();
1348                 }
1349                 devtab[tr->c->type]->bwrite(tr->c, nb, 0);
1350                 poperror();
1351         }
1352         qunlock(&out->io);
1353         poperror();
1354 }
1355
1356 static long
1357 tlsbwrite(Chan *c, Block *b, ulong offset)
1358 {
1359         int ty;
1360         ulong n;
1361         TlsRec *tr;
1362
1363         n = BLEN(b);
1364
1365         tr = tlsdevs[CONV(c->qid)];
1366         if(tr == nil)
1367                 panic("tlsbwrite");
1368
1369         ty = TYPE(c->qid);
1370         switch(ty) {
1371         default:
1372                 return devbwrite(c, b, offset);
1373         case Qhand:
1374                 tlsrecwrite(tr, RHandshake, b);
1375                 tr->handout += n;
1376                 break;
1377         case Qdata:
1378                 checkstate(tr, 0, SOpen);
1379                 tlsrecwrite(tr, RApplication, b);
1380                 tr->dataout += n;
1381                 break;
1382         }
1383
1384         return n;
1385 }
1386
1387 typedef struct Hashalg Hashalg;
1388 struct Hashalg
1389 {
1390         char    *name;
1391         int     maclen;
1392         void    (*initkey)(Hashalg *, int, Secret *, uchar*);
1393 };
1394
1395 static void
1396 initmd5key(Hashalg *ha, int version, Secret *s, uchar *p)
1397 {
1398         s->maclen = ha->maclen;
1399         if(version == SSL3Version)
1400                 s->mac = sslmac_md5;
1401         else
1402                 s->mac = hmac_md5;
1403         memmove(s->mackey, p, ha->maclen);
1404 }
1405
1406 static void
1407 initclearmac(Hashalg *, int, Secret *s, uchar *)
1408 {
1409         s->mac = nomac;
1410 }
1411
1412 static void
1413 initsha1key(Hashalg *ha, int version, Secret *s, uchar *p)
1414 {
1415         s->maclen = ha->maclen;
1416         if(version == SSL3Version)
1417                 s->mac = sslmac_sha1;
1418         else
1419                 s->mac = hmac_sha1;
1420         memmove(s->mackey, p, ha->maclen);
1421 }
1422
1423 static void
1424 initsha2_256key(Hashalg *ha, int version, Secret *s, uchar *p)
1425 {
1426         if(version == SSL3Version)
1427                 error("sha256 cannot be used with SSL");
1428         s->maclen = ha->maclen;
1429         s->mac = hmac_sha2_256;
1430         memmove(s->mackey, p, ha->maclen);
1431 }
1432
1433 static Hashalg hashtab[] =
1434 {
1435         { "clear",      0,              initclearmac, },
1436         { "md5",        MD5dlen,        initmd5key, },
1437         { "sha1",       SHA1dlen,       initsha1key, },
1438         { "sha256",     SHA2_256dlen,   initsha2_256key, },
1439         { 0 }
1440 };
1441
1442 static Hashalg*
1443 parsehashalg(char *p)
1444 {
1445         Hashalg *ha;
1446
1447         for(ha = hashtab; ha->name; ha++)
1448                 if(strcmp(p, ha->name) == 0)
1449                         return ha;
1450         error("unsupported hash algorithm");
1451         return nil;
1452 }
1453
1454 typedef struct Encalg Encalg;
1455 struct Encalg
1456 {
1457         char    *name;
1458         int     keylen;
1459         int     ivlen;
1460         void    (*initkey)(Encalg *ea, Secret *, uchar*, uchar*);
1461 };
1462
1463 static void
1464 initRC4key(Encalg *ea, Secret *s, uchar *p, uchar *)
1465 {
1466         s->enckey = secalloc(sizeof(RC4state));
1467         s->enc = rc4enc;
1468         s->dec = rc4enc;
1469         setupRC4state(s->enckey, p, ea->keylen);
1470 }
1471
1472 static void
1473 initDES3key(Encalg *, Secret *s, uchar *p, uchar *iv)
1474 {
1475         s->enckey = secalloc(sizeof(DES3state));
1476         s->enc = des3enc;
1477         s->dec = des3dec;
1478         s->block = 8;
1479         setupDES3state(s->enckey, (uchar(*)[8])p, iv);
1480 }
1481
1482 static void
1483 initAESkey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
1484 {
1485         s->enckey = secalloc(sizeof(AESstate));
1486         s->enc = aesenc;
1487         s->dec = aesdec;
1488         s->block = 16;
1489         setupAESstate(s->enckey, p, ea->keylen, iv);
1490 }
1491
1492 static void
1493 initccpolykey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
1494 {
1495         s->enckey = secalloc(sizeof(Chachastate));
1496         s->aead_enc = ccpoly_aead_enc;
1497         s->aead_dec = ccpoly_aead_dec;
1498         s->maclen = Poly1305dlen;
1499         if(ea->ivlen == 0) {
1500                 /* older draft version, iv is 64-bit sequence number */
1501                 setupChachastate(s->enckey, p, ea->keylen, nil, 64/8, 20);
1502         } else {
1503                 /* IETF standard, 96-bit iv xored with sequence number */
1504                 memmove(s->mackey, iv, ea->ivlen);
1505                 setupChachastate(s->enckey, p, ea->keylen, iv, ea->ivlen, 20);
1506         }
1507 }
1508
1509 static void
1510 initaesgcmkey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
1511 {
1512         s->enckey = secalloc(sizeof(AESGCMstate));
1513         s->aead_enc = aesgcm_aead_enc;
1514         s->aead_dec = aesgcm_aead_dec;
1515         s->maclen = 16;
1516         s->recivlen = 8;
1517         memmove(s->mackey, iv, ea->ivlen);
1518         prng(s->mackey + ea->ivlen, s->recivlen);
1519         setupAESGCMstate(s->enckey, p, ea->keylen, nil, 0);
1520 }
1521
1522 static void
1523 initclearenc(Encalg *, Secret *s, uchar *, uchar *)
1524 {
1525         s->enc = noenc;
1526         s->dec = noenc;
1527 }
1528
1529 static Encalg encrypttab[] =
1530 {
1531         { "clear", 0, 0, initclearenc },
1532         { "rc4_128", 128/8, 0, initRC4key },
1533         { "3des_ede_cbc", 3 * 8, 8, initDES3key },
1534         { "aes_128_cbc", 128/8, 16, initAESkey },
1535         { "aes_256_cbc", 256/8, 16, initAESkey },
1536         { "ccpoly64_aead", 256/8, 0, initccpolykey },
1537         { "ccpoly96_aead", 256/8, 96/8, initccpolykey },
1538         { "aes_128_gcm_aead", 128/8, 4, initaesgcmkey },
1539         { "aes_256_gcm_aead", 256/8, 4, initaesgcmkey },
1540         { 0 }
1541 };
1542
1543 static Encalg*
1544 parseencalg(char *p)
1545 {
1546         Encalg *ea;
1547
1548         for(ea = encrypttab; ea->name; ea++)
1549                 if(strcmp(p, ea->name) == 0)
1550                         return ea;
1551         error("unsupported encryption algorithm");
1552         return nil;
1553 }
1554
1555 static long
1556 tlswrite(Chan *c, void *a, long n, vlong off)
1557 {
1558         Encalg *ea;
1559         Hashalg *ha;
1560         TlsRec *volatile tr;
1561         Secret *volatile tos, *volatile toc;
1562         Block *volatile b;
1563         Cmdbuf *volatile cb;
1564         int m, ty;
1565         char *p, *e;
1566         uchar *volatile x;
1567         ulong offset = off;
1568
1569         tr = tlsdevs[CONV(c->qid)];
1570         if(tr == nil)
1571                 panic("tlswrite");
1572
1573         ty = TYPE(c->qid);
1574         switch(ty){
1575         case Qdata:
1576         case Qhand:
1577                 p = a;
1578                 e = p + n;
1579                 do{
1580                         m = e - p;
1581                         if(m > c->iounit)
1582                                 m = c->iounit;
1583
1584                         b = allocb(m);
1585                         if(waserror()){
1586                                 freeb(b);
1587                                 nexterror();
1588                         }
1589                         memmove(b->wp, p, m);
1590                         poperror();
1591                         b->wp += m;
1592
1593                         tlsbwrite(c, b, offset);
1594
1595                         p += m;
1596                 }while(p < e);
1597                 return n;
1598         case Qctl:
1599                 break;
1600         default:
1601                 error(Ebadusefd);
1602                 return -1;
1603         }
1604
1605         cb = parsecmd(a, n);
1606         if(waserror()){
1607                 free(cb);
1608                 nexterror();
1609         }
1610         if(cb->nf < 1)
1611                 error("short control request");
1612
1613         /* mutex with operations using what we're about to change */
1614         if(waserror()){
1615                 qunlock(&tr->in.seclock);
1616                 qunlock(&tr->out.seclock);
1617                 nexterror();
1618         }
1619         qlock(&tr->in.seclock);
1620         qlock(&tr->out.seclock);
1621
1622         if(strcmp(cb->f[0], "fd") == 0){
1623                 if(cb->nf != 3)
1624                         error("usage: fd open-fd version");
1625                 if(tr->c != nil)
1626                         error(Einuse);
1627                 m = strtol(cb->f[2], nil, 0);
1628                 if(m < MinProtoVersion || m > MaxProtoVersion)
1629                         error("unsupported version");
1630                 tr->c = buftochan(cb->f[1]);
1631                 tr->version = m;
1632                 tlsSetState(tr, SHandshake, SClosed);
1633         }else if(strcmp(cb->f[0], "version") == 0){
1634                 if(cb->nf != 2)
1635                         error("usage: version vers");
1636                 if(tr->c == nil)
1637                         error("must set fd before version");
1638                 if(tr->verset)
1639                         error("version already set");
1640                 m = strtol(cb->f[1], nil, 0);
1641                 if(m < MinProtoVersion || m > MaxProtoVersion)
1642                         error("unsupported version");
1643                 if(m == SSL3Version)
1644                         tr->packAAD = sslPackAAD;
1645                 else
1646                         tr->packAAD = tlsPackAAD;
1647                 tr->verset = 1;
1648                 tr->version = m;
1649         }else if(strcmp(cb->f[0], "secret") == 0){
1650                 if(cb->nf != 5)
1651                         error("usage: secret hashalg encalg isclient secretdata");
1652                 if(tr->c == nil || !tr->verset)
1653                         error("must set fd and version before secrets");
1654
1655                 if(tr->in.new != nil){
1656                         freeSec(tr->in.new);
1657                         tr->in.new = nil;
1658                 }
1659                 if(tr->out.new != nil){
1660                         freeSec(tr->out.new);
1661                         tr->out.new = nil;
1662                 }
1663
1664                 ha = parsehashalg(cb->f[1]);
1665                 ea = parseencalg(cb->f[2]);
1666
1667                 p = cb->f[4];
1668                 m = (strlen(p)*3)/2 + 1;
1669                 x = secalloc(m);
1670                 tos = secalloc(sizeof(Secret));
1671                 toc = secalloc(sizeof(Secret));
1672                 if(waserror()){
1673                         secfree(x);
1674                         freeSec(tos);
1675                         freeSec(toc);
1676                         nexterror();
1677                 }
1678
1679                 m = dec64(x, m, p, strlen(p));
1680                 memset(p, 0, strlen(p));
1681                 if(m < 2 * ha->maclen + 2 * ea->keylen + 2 * ea->ivlen)
1682                         error("not enough secret data provided");
1683
1684                 if(!ha->initkey || !ea->initkey)
1685                         error("misimplemented secret algorithm");
1686
1687                 (*ha->initkey)(ha, tr->version, tos, &x[0]);
1688                 (*ha->initkey)(ha, tr->version, toc, &x[ha->maclen]);
1689                 (*ea->initkey)(ea, tos, &x[2 * ha->maclen], &x[2 * ha->maclen + 2 * ea->keylen]);
1690                 (*ea->initkey)(ea, toc, &x[2 * ha->maclen + ea->keylen], &x[2 * ha->maclen + 2 * ea->keylen + ea->ivlen]);
1691
1692                 if(!tos->aead_enc || !tos->aead_dec || !toc->aead_enc || !toc->aead_dec)
1693                         if(!tos->mac || !tos->enc || !tos->dec || !toc->mac || !toc->enc || !toc->dec)
1694                                 error("missing algorithm implementations");
1695
1696                 if(strtol(cb->f[3], nil, 0) == 0){
1697                         tr->in.new = tos;
1698                         tr->out.new = toc;
1699                 }else{
1700                         tr->in.new = toc;
1701                         tr->out.new = tos;
1702                 }
1703                 if(tr->version == SSL3Version){
1704                         toc->unpad = sslunpad;
1705                         tos->unpad = sslunpad;
1706                 }else{
1707                         toc->unpad = tlsunpad;
1708                         tos->unpad = tlsunpad;
1709                 }
1710                 toc->encalg = ea->name;
1711                 toc->hashalg = ha->name;
1712                 tos->encalg = ea->name;
1713                 tos->hashalg = ha->name;
1714
1715                 secfree(x);
1716                 poperror();
1717         }else if(strcmp(cb->f[0], "changecipher") == 0){
1718                 if(cb->nf != 1)
1719                         error("usage: changecipher");
1720                 if(tr->out.new == nil)
1721                         error("cannot change cipher spec without setting secret");
1722
1723                 qunlock(&tr->in.seclock);
1724                 qunlock(&tr->out.seclock);
1725                 poperror();
1726                 free(cb);
1727                 poperror();
1728
1729                 /*
1730                  * the real work is done as the message is written
1731                  * so the stream is encrypted in sync.
1732                  */
1733                 b = allocb(1);
1734                 *b->wp++ = 1;
1735                 tlsrecwrite(tr, RChangeCipherSpec, b);
1736                 return n;
1737         }else if(strcmp(cb->f[0], "opened") == 0){
1738                 if(cb->nf != 1)
1739                         error("usage: opened");
1740                 if(tr->in.sec == nil || tr->out.sec == nil)
1741                         error("cipher must be configured before enabling data messages");
1742                 lock(&tr->statelk);
1743                 if(tr->state != SHandshake && tr->state != SOpen){
1744                         unlock(&tr->statelk);
1745                         error("cannot enable data messages");
1746                 }
1747                 tr->state = SOpen;
1748                 unlock(&tr->statelk);
1749                 tr->opened = 1;
1750         }else if(strcmp(cb->f[0], "alert") == 0){
1751                 if(cb->nf != 2)
1752                         error("usage: alert n");
1753                 if(tr->c == nil)
1754                         error("must set fd before sending alerts");
1755                 m = strtol(cb->f[1], nil, 0);
1756
1757                 qunlock(&tr->in.seclock);
1758                 qunlock(&tr->out.seclock);
1759                 poperror();
1760                 free(cb);
1761                 poperror();
1762
1763                 sendAlert(tr, m);
1764
1765                 if(m == ECloseNotify)
1766                         tlsclosed(tr, SLClose);
1767
1768                 return n;
1769         } else if(strcmp(cb->f[0], "debug") == 0){
1770                 if(cb->nf == 2){
1771                         if(strcmp(cb->f[1], "on") == 0)
1772                                 tr->debug = 1;
1773                         else
1774                                 tr->debug = 0;
1775                 } else
1776                         tr->debug = 1;
1777         } else
1778                 error(Ebadarg);
1779
1780         qunlock(&tr->in.seclock);
1781         qunlock(&tr->out.seclock);
1782         poperror();
1783         free(cb);
1784         poperror();
1785
1786         return n;
1787 }
1788
1789 static void
1790 tlsinit(void)
1791 {
1792         struct Encalg *e;
1793         struct Hashalg *h;
1794         int n;
1795         char *cp;
1796         static int already;
1797
1798         if(!already){
1799                 fmtinstall('H', encodefmt);
1800                 already = 1;
1801         }
1802
1803         tlsdevs = smalloc(sizeof(TlsRec*) * maxtlsdevs);
1804         trnames = smalloc((sizeof *trnames) * maxtlsdevs);
1805
1806         n = 1;
1807         for(e = encrypttab; e->name != nil; e++)
1808                 n += strlen(e->name) + 1;
1809         cp = encalgs = smalloc(n);
1810         for(e = encrypttab;;){
1811                 strcpy(cp, e->name);
1812                 cp += strlen(e->name);
1813                 e++;
1814                 if(e->name == nil)
1815                         break;
1816                 *cp++ = ' ';
1817         }
1818         *cp = 0;
1819
1820         n = 1;
1821         for(h = hashtab; h->name != nil; h++)
1822                 n += strlen(h->name) + 1;
1823         cp = hashalgs = smalloc(n);
1824         for(h = hashtab;;){
1825                 strcpy(cp, h->name);
1826                 cp += strlen(h->name);
1827                 h++;
1828                 if(h->name == nil)
1829                         break;
1830                 *cp++ = ' ';
1831         }
1832         *cp = 0;
1833 }
1834
1835 Dev tlsdevtab = {
1836         'a',
1837         "tls",
1838
1839         devreset,
1840         tlsinit,
1841         devshutdown,
1842         tlsattach,
1843         tlswalk,
1844         tlsstat,
1845         tlsopen,
1846         devcreate,
1847         tlsclose,
1848         tlsread,
1849         tlsbread,
1850         tlswrite,
1851         tlsbwrite,
1852         devremove,
1853         tlswstat,
1854 };
1855
1856 /* get channel associated with an fd */
1857 static Chan*
1858 buftochan(char *p)
1859 {
1860         Chan *c;
1861         int fd;
1862
1863         if(p == 0)
1864                 error(Ebadarg);
1865         fd = strtoul(p, 0, 0);
1866         if(fd < 0)
1867                 error(Ebadarg);
1868         c = fdtochan(fd, ORDWR, 1, 1);  /* error check and inc ref */
1869         return c;
1870 }
1871
1872 static void
1873 sendAlert(TlsRec *tr, int err)
1874 {
1875         Block *b;
1876         int i, fatal;
1877         char *msg;
1878
1879 if(tr->debug)pprint("sendAlert %d\n", err);
1880         fatal = 1;
1881         msg = "tls unknown alert";
1882         for(i=0; i < nelem(tlserrs); i++) {
1883                 if(tlserrs[i].err == err) {
1884                         msg = tlserrs[i].msg;
1885                         if(tr->version == SSL3Version)
1886                                 err = tlserrs[i].sslerr;
1887                         else
1888                                 err = tlserrs[i].tlserr;
1889                         fatal = tlserrs[i].fatal;
1890                         break;
1891                 }
1892         }
1893
1894         if(!waserror()){
1895                 b = allocb(2);
1896                 *b->wp++ = fatal + 1;
1897                 *b->wp++ = err;
1898                 if(fatal)
1899                         tlsSetState(tr, SAlert, SOpen|SHandshake|SRClose);
1900                 tlsrecwrite(tr, RAlert, b);
1901                 poperror();
1902         }
1903         if(fatal)
1904                 tlsError(tr, msg);
1905 }
1906
1907 static void
1908 tlsError(TlsRec *tr, char *msg)
1909 {
1910         int s;
1911
1912 if(tr->debug)pprint("tlsError %s\n", msg);
1913         lock(&tr->statelk);
1914         s = tr->state;
1915         tr->state = SError;
1916         if(s != SError){
1917                 strncpy(tr->err, msg, ERRMAX - 1);
1918                 tr->err[ERRMAX - 1] = '\0';
1919         }
1920         unlock(&tr->statelk);
1921         if(s != SError)
1922                 alertHand(tr, msg);
1923 }
1924
1925 static void
1926 tlsSetState(TlsRec *tr, int new, int old)
1927 {
1928         lock(&tr->statelk);
1929         if(tr->state & old)
1930                 tr->state = new;
1931         unlock(&tr->statelk);
1932 }
1933
1934 /* hand up a digest connection */
1935 static void
1936 tlshangup(TlsRec *tr)
1937 {
1938         Block *b;
1939
1940         qlock(&tr->in.io);
1941         for(b = tr->processed; b; b = tr->processed){
1942                 tr->processed = b->next;
1943                 freeb(b);
1944         }
1945         if(tr->unprocessed != nil){
1946                 freeb(tr->unprocessed);
1947                 tr->unprocessed = nil;
1948         }
1949         qunlock(&tr->in.io);
1950
1951         tlsSetState(tr, SClosed, ~0);
1952 }
1953
1954 static TlsRec*
1955 newtls(Chan *ch)
1956 {
1957         TlsRec **pp, **ep, **np;
1958         char **nmp;
1959         int t, newmax;
1960
1961         if(waserror()) {
1962                 unlock(&tdlock);
1963                 nexterror();
1964         }
1965         lock(&tdlock);
1966         ep = &tlsdevs[maxtlsdevs];
1967         for(pp = tlsdevs; pp < ep; pp++)
1968                 if(*pp == nil)
1969                         break;
1970         if(pp >= ep) {
1971                 if(maxtlsdevs >= MaxTlsDevs) {
1972                         unlock(&tdlock);
1973                         poperror();
1974                         return nil;
1975                 }
1976                 newmax = 2 * maxtlsdevs;
1977                 if(newmax > MaxTlsDevs)
1978                         newmax = MaxTlsDevs;
1979                 np = smalloc(sizeof(TlsRec*) * newmax);
1980                 memmove(np, tlsdevs, sizeof(TlsRec*) * maxtlsdevs);
1981                 tlsdevs = np;
1982                 pp = &tlsdevs[maxtlsdevs];
1983                 memset(pp, 0, sizeof(TlsRec*)*(newmax - maxtlsdevs));
1984
1985                 nmp = smalloc(sizeof *nmp * newmax);
1986                 memmove(nmp, trnames, sizeof *nmp * maxtlsdevs);
1987                 trnames = nmp;
1988
1989                 maxtlsdevs = newmax;
1990         }
1991         *pp = mktlsrec();
1992         if(pp - tlsdevs >= tdhiwat)
1993                 tdhiwat++;
1994         t = TYPE(ch->qid);
1995         if(t == Qclonus)
1996                 t = Qctl;
1997         ch->qid.path = QID(pp - tlsdevs, t);
1998         ch->qid.vers = 0;
1999         unlock(&tdlock);
2000         poperror();
2001         return *pp;
2002 }
2003
2004 static TlsRec *
2005 mktlsrec(void)
2006 {
2007         TlsRec *tr;
2008
2009         tr = mallocz(sizeof(*tr), 1);
2010         if(tr == nil)
2011                 error(Enomem);
2012         tr->state = SClosed;
2013         tr->ref = 1;
2014         kstrdup(&tr->user, up->user);
2015         tr->perm = 0660;
2016         return tr;
2017 }
2018
2019 static char*
2020 tlsstate(int s)
2021 {
2022         switch(s){
2023         case SHandshake:
2024                 return "Handshaking";
2025         case SOpen:
2026                 return "Established";
2027         case SRClose:
2028                 return "RemoteClosed";
2029         case SLClose:
2030                 return "LocalClosed";
2031         case SAlert:
2032                 return "Alerting";
2033         case SError:
2034                 return "Errored";
2035         case SClosed:
2036                 return "Closed";
2037         }
2038         return "Unknown";
2039 }
2040
2041 static void
2042 freeSec(Secret *s)
2043 {
2044         if(s == nil)
2045                 return;
2046         secfree(s->enckey);
2047         secfree(s);
2048 }
2049
2050 static int
2051 noenc(Secret *, uchar *, int n)
2052 {
2053         return n;
2054 }
2055
2056 static int
2057 rc4enc(Secret *sec, uchar *buf, int n)
2058 {
2059         rc4(sec->enckey, buf, n);
2060         return n;
2061 }
2062
2063 static int
2064 tlsunpad(uchar *buf, int n, int block)
2065 {
2066         int pad, nn;
2067
2068         pad = buf[n - 1];
2069         nn = n - 1 - pad;
2070         if(nn <= 0 || n % block)
2071                 return -1;
2072         while(--n > nn)
2073                 if(pad != buf[n - 1])
2074                         return -1;
2075         return nn;
2076 }
2077
2078 static int
2079 sslunpad(uchar *buf, int n, int block)
2080 {
2081         int pad, nn;
2082
2083         pad = buf[n - 1];
2084         nn = n - 1 - pad;
2085         if(nn <= 0 || n % block)
2086                 return -1;
2087         return nn;
2088 }
2089
2090 static int
2091 blockpad(uchar *buf, int n, int block)
2092 {
2093         int pad, nn;
2094
2095         nn = n + block;
2096         nn -= nn % block;
2097         pad = nn - (n + 1);
2098         while(n < nn)
2099                 buf[n++] = pad;
2100         return nn;
2101 }
2102                 
2103 static int
2104 des3enc(Secret *sec, uchar *buf, int n)
2105 {
2106         n = blockpad(buf, n, 8);
2107         des3CBCencrypt(buf, n, sec->enckey);
2108         return n;
2109 }
2110
2111 static int
2112 des3dec(Secret *sec, uchar *buf, int n)
2113 {
2114         des3CBCdecrypt(buf, n, sec->enckey);
2115         return (*sec->unpad)(buf, n, 8);
2116 }
2117
2118 static int
2119 aesenc(Secret *sec, uchar *buf, int n)
2120 {
2121         n = blockpad(buf, n, 16);
2122         aesCBCencrypt(buf, n, sec->enckey);
2123         return n;
2124 }
2125
2126 static int
2127 aesdec(Secret *sec, uchar *buf, int n)
2128 {
2129         aesCBCdecrypt(buf, n, sec->enckey);
2130         return (*sec->unpad)(buf, n, 16);
2131 }
2132
2133 static void
2134 ccpoly_aead_setiv(Secret *sec, uchar seq[8])
2135 {
2136         uchar iv[ChachaIVlen];
2137         Chachastate *cs;
2138         int i;
2139
2140         cs = (Chachastate*)sec->enckey;
2141         if(cs->ivwords == 2){
2142                 chacha_setiv(cs, seq);
2143                 return;
2144         }
2145
2146         memmove(iv, sec->mackey, ChachaIVlen);
2147         for(i=0; i<8; i++)
2148                 iv[i+(ChachaIVlen-8)] ^= seq[i];
2149
2150         chacha_setiv(cs, iv);
2151
2152         memset(iv, 0, sizeof(iv));
2153 }
2154
2155 static int
2156 ccpoly_aead_enc(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data, int len)
2157 {
2158         USED(reciv);
2159         ccpoly_aead_setiv(sec, aad);
2160         ccpoly_encrypt(data, len, aad, aadlen, data+len, sec->enckey);
2161         return len + sec->maclen;
2162 }
2163
2164 static int
2165 ccpoly_aead_dec(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data, int len)
2166 {
2167         USED(reciv);
2168         len -= sec->maclen;
2169         if(len < 0)
2170                 return -1;
2171         ccpoly_aead_setiv(sec, aad);
2172         if(ccpoly_decrypt(data, len, aad, aadlen, data+len, sec->enckey) != 0)
2173                 return -1;
2174         return len;
2175 }
2176
2177 static int
2178 aesgcm_aead_enc(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data, int len)
2179 {
2180         uchar iv[12];
2181         int i;
2182
2183         memmove(iv, sec->mackey, 4+8);
2184         for(i=0; i<8; i++) iv[4+i] ^= aad[i];
2185         memmove(reciv, iv+4, 8);
2186         aesgcm_setiv(sec->enckey, iv, 12);
2187         memset(iv, 0, sizeof(iv));
2188         aesgcm_encrypt(data, len, aad, aadlen, data+len, sec->enckey);
2189         return len + sec->maclen;
2190 }
2191
2192 static int
2193 aesgcm_aead_dec(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data, int len)
2194 {
2195         uchar iv[12];
2196
2197         len -= sec->maclen;
2198         if(len < 0)
2199                 return -1;
2200         memmove(iv, sec->mackey, 4);
2201         memmove(iv+4, reciv, 8);
2202         aesgcm_setiv(sec->enckey, iv, 12);
2203         memset(iv, 0, sizeof(iv));
2204         if(aesgcm_decrypt(data, len, aad, aadlen, data+len, sec->enckey) != 0)
2205                 return -1;
2206         return len;
2207 }
2208
2209
2210 static DigestState*
2211 nomac(uchar *, ulong, uchar *, ulong, uchar *, DigestState *)
2212 {
2213         return nil;
2214 }
2215
2216 /*
2217  * sslmac: mac calculations for ssl 3.0 only; tls 1.0 uses the standard hmac.
2218  */
2219 static DigestState*
2220 sslmac_x(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s,
2221         DigestState*(*x)(uchar*, ulong, uchar*, DigestState*), int xlen, int padlen)
2222 {
2223         int i;
2224         uchar pad[48], innerdigest[20];
2225
2226         if(xlen > sizeof(innerdigest)
2227         || padlen > sizeof(pad))
2228                 return nil;
2229
2230         if(klen>64)
2231                 return nil;
2232
2233         /* first time through */
2234         if(s == nil){
2235                 for(i=0; i<padlen; i++)
2236                         pad[i] = 0x36;
2237                 s = (*x)(key, klen, nil, nil);
2238                 s = (*x)(pad, padlen, nil, s);
2239                 if(s == nil)
2240                         return nil;
2241         }
2242
2243         s = (*x)(p, len, nil, s);
2244         if(digest == nil)
2245                 return s;
2246
2247         /* last time through */
2248         for(i=0; i<padlen; i++)
2249                 pad[i] = 0x5c;
2250         (*x)(nil, 0, innerdigest, s);
2251         s = (*x)(key, klen, nil, nil);
2252         s = (*x)(pad, padlen, nil, s);
2253         (*x)(innerdigest, xlen, digest, s);
2254         return nil;
2255 }
2256
2257 static DigestState*
2258 sslmac_sha1(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s)
2259 {
2260         return sslmac_x(p, len, key, klen, digest, s, sha1, SHA1dlen, 40);
2261 }
2262
2263 static DigestState*
2264 sslmac_md5(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s)
2265 {
2266         return sslmac_x(p, len, key, klen, digest, s, md5, MD5dlen, 48);
2267 }
2268
2269 static int
2270 sslPackAAD(u64int seq, uchar *hdr, uchar *aad)
2271 {
2272         put64(aad, seq);
2273         aad[8] = hdr[0];
2274         aad[9] = hdr[3];
2275         aad[10] = hdr[4];
2276         return 11;
2277 }
2278
2279 static int
2280 tlsPackAAD(u64int seq, uchar *hdr, uchar *aad)
2281 {
2282         put64(aad, seq);
2283         aad[8] = hdr[0];
2284         aad[9] = hdr[1];
2285         aad[10] = hdr[2];
2286         aad[11] = hdr[3];
2287         aad[12] = hdr[4];
2288         return 13;
2289 }
2290
2291 static void
2292 packMac(Secret *sec, uchar *aad, int aadlen, uchar *body, int bodylen, uchar *mac)
2293 {
2294         DigestState *s;
2295
2296         s = (*sec->mac)(aad, aadlen, sec->mackey, sec->maclen, nil, nil);
2297         (*sec->mac)(body, bodylen, sec->mackey, sec->maclen, mac, s);
2298 }
2299
2300 static void
2301 put32(uchar *p, u32int x)
2302 {
2303         p[0] = x>>24;
2304         p[1] = x>>16;
2305         p[2] = x>>8;
2306         p[3] = x;
2307 }
2308
2309 static void
2310 put64(uchar *p, u64int x)
2311 {
2312         put32(p, x >> 32);
2313         put32(p+4, x);
2314 }
2315
2316 static void
2317 put24(uchar *p, int x)
2318 {
2319         p[0] = x>>16;
2320         p[1] = x>>8;
2321         p[2] = x;
2322 }
2323
2324 static void
2325 put16(uchar *p, int x)
2326 {
2327         p[0] = x>>8;
2328         p[1] = x;
2329 }
2330
2331 static int
2332 get16(uchar *p)
2333 {
2334         return (p[0]<<8)|p[1];
2335 }
2336
2337 static char *charmap = "0123456789abcdef";
2338
2339 static void
2340 pdump(int len, void *a, char *tag)
2341 {
2342         uchar *p;
2343         int i;
2344         char buf[65+32];
2345         char *q;
2346
2347         p = a;
2348         strcpy(buf, tag);
2349         while(len > 0){
2350                 q = buf + strlen(tag);
2351                 for(i = 0; len > 0 && i < 32; i++){
2352                         if(*p >= ' ' && *p < 0x7f){
2353                                 *q++ = ' ';
2354                                 *q++ = *p;
2355                         } else {
2356                                 *q++ = charmap[*p>>4];
2357                                 *q++ = charmap[*p & 0xf];
2358                         }
2359                         len--;
2360                         p++;
2361                 }
2362                 *q = 0;
2363
2364                 if(len > 0)
2365                         pprint("%s...\n", buf);
2366                 else
2367                         pprint("%s\n", buf);
2368         }
2369 }