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