ref: fe00d007d93413d37e138202ace03eb6a2b59748
parent: ecdf17034b03e4a866651dba39ac4b5206f4a460
author: halfwit <michaelmisch1985@gmail.com>
date: Wed Feb 28 17:53:22 PST 2024
Take out as much as we can for unused libs. draw stays, as it gets used later
--- a/Makefile
+++ b/Makefile
@@ -5,25 +5,18 @@
OFILES=\
main.$O\
aan.$O\
- secstore.$O\
latin1.$O\
- $(OS)-factotum.$O\
+ getuser.$O\
$(XOFILES)\
LIBS1=\
kern/libkern.a\
- exportfs/libexportfs.a\
- libauth/libauth.a\
- libauthsrv/libauthsrv.a\
- libsec/libsec.a\
rc/librc.a\
- libmp/libmp.a\
libmemdraw/libmemdraw.a\
libmemlayer/libmemlayer.a\
libdraw/libdraw.a\
gui-$(GUI)/libgui.a\
libc/libc.a\
- libip/libip.a\
# stupid gcc
LIBS=$(LIBS1) libmachdep.a
@@ -41,21 +34,7 @@
kern/libkern.a:
(cd kern; $(MAKE))
-exportfs/libexportfs.a:
- (cd exportfs; $(MAKE))
-libauth/libauth.a:
- (cd libauth; $(MAKE))
-
-libauthsrv/libauthsrv.a:
- (cd libauthsrv; $(MAKE))
-
-libmp/libmp.a:
- (cd libmp; $(MAKE))
-
-libsec/libsec.a:
- (cd libsec; $(MAKE))
-
libmemdraw/libmemdraw.a:
(cd libmemdraw; $(MAKE))
@@ -67,9 +46,6 @@
libc/libc.a:
(cd libc; $(MAKE))
-
-libip/libip.a:
- (cd libip; $(MAKE))
rc/librc.a:
(cd rc; $(MAKE))
--- a/cpu.c.bak
+++ /dev/null
@@ -1,937 +1,0 @@
-/*
- * cpu.c - Make a connection to a cpu server
- */
-
-#include <u.h>
-#include <libc.h>
-#include <auth.h>
-#include <fcall.h>
-#include <authsrv.h>
-#include <libsec.h>
-#include "args.h"
-#include "drawcpu.h"
-
-#define MaxStr 128
-
-static void usage(void);
-static void writestr(int, char*, char*, int);
-static int readstr(int, char*, int);
-static char *keyspec = "";
-static AuthInfo *p9any(int);
-static int getkey(Authkey*, char*, char*, char*, char*);
-static int findkey(Authkey*, char*, char*, char*);
-
-static char *host;
-static int aanfilter;
-static int aanto = 3600 * 24;
-static int norcpu;
-static int nokbd;
-static int nogfx;
-static int nineflag;
-
-static char *ealgs = "rc4_256 sha1";
-
-/* authentication mechanisms */
-static int p9authssl(int);
-static int p9authtls(int);
-
-char *authserver;
-char *secstore;
-char *user, *pass;
-char secstorebuf[65536];
-char *geometry;
-
-extern void guimain(void);
-
-char*
-estrdup(char *s)
-{
- s = strdup(s);
- if(s == nil)
- sysfatal("out of memory");
- return s;
-}
-
-static void
-ending(void)
-{
- panic("ending");
-}
-
-int
-mountfactotum(void)
-{
- int fd;
-
- if((fd = dialfactotum()) < 0)
- return -1;
- if(sysmount(fd, -1, "/mnt/factotum", MREPL, "") < 0){
- fprint(2, "mount factotum: %r\n");
- return -1;
- }
- if((fd = open("/mnt/factotum/ctl", OREAD)) < 0){
- fprint(2, "open /mnt/factotum/ctl: %r\n");
- return -1;
- }
- close(fd);
- return 0;
-}
-
-static int
-startaan(char *host, int fd)
-{
- static char script[] =
-"~ $#netdir 1 || netdir=/net/tcp/clone\n"
-"netdir=`{basename -d $netdir} || exit\n"
-"<>$netdir/clone {\n"
-" netdir=$netdir/`{read} || exit\n"
-" >[3] $netdir/ctl {\n"
-" echo -n 'announce *!0' >[1=3]\n"
-" echo `{cat $netdir/local} || exit\n"
-" bind '#|' /mnt/aan || exit\n"
-" exec aan -m $aanto $netdir <>/mnt/aan/data1 >[1=0] >[2]/dev/null &\n"
-" }\n"
-"}\n"
-"<>/mnt/aan/data >[1=0] >[2]/dev/null {\n"
-" rfork n\n"
-" fn server {\n"
-" echo -n aanserver $netdir >/proc/$pid/args\n"
-" rm -f /env/^('fn#server' aanto)\n"
-" . <{n=`{read} && ! ~ $#n 0 && read -c $n} >[2=1]\n"
-" }\n"
-" exec tlssrv -A /bin/rc -c server\n"
-" exit\n"
-"}\n";
- char buf[128], *p, *na;
- int n;
-
- snprint(buf, sizeof buf, "aanto=%d\n", aanto);
- if(fprint(fd, "%7ld\n%s%s", strlen(buf)+strlen(script), buf, script) < 0)
- sysfatal("sending aan script: %r");
- n = read(fd, buf, sizeof(buf)-1);
- close(fd);
-
- while(n > 0 && buf[n-1] == '\n') n--;
- if(n <= 0) return -1;
- buf[n] = 0;
- if((p = strrchr(buf, '!')) != nil)
- na = strdup(netmkaddr(host, "tcp", p+1));
- else
- na = strdup(buf);
-
- return aanclient(na, aanto);
-}
-
-static void
-rcpuexit(void)
-{
- char *s = getenv("rstatus");
- if(s != nil)
- exit(*s);
-}
-
-void
-rcpu(char *host, char *cmd)
-{
- static char script[] =
-"mount -nc /fd/0 /mnt/term || exit\n"
-"bind -q /mnt/term/dev/cons /dev/cons\n"
-"if(test -r /mnt/term/dev/kbd){\n"
-" </dev/cons >/dev/cons >[2=1] aux/kbdfs -dq -m /mnt/term/dev\n"
-" bind -q /mnt/term/dev/cons /dev/cons\n"
-"}\n"
-"</dev/cons >/dev/cons >[2=1] service=cpu %s\n"
-"echo -n $status >/mnt/term/env/rstatus >[2]/dev/null\n"
-"echo -n hangup >/proc/$pid/notepg\n";
- int fd;
-
- if((fd = dial(netmkaddr(host, "tcp", "rcpu"), nil, nil, nil)) < 0)
- return;
-
- /* provide /dev/kbd for kbdfs */
- if(!nokbd)
- bind("#b", "/dev", MAFTER);
-
- fd = p9authtls(fd);
- if(aanfilter){
- fd = startaan(host, fd);
- if(fd < 0)
- sysfatal("startaan: %r");
- fd = p9authtls(fd);
- }
- memset(secstorebuf, 0, sizeof(secstorebuf)); /* forget secstore secrets */
-
- if(cmd == nil)
- cmd = smprint(script, "rc -li");
- else {
- char *run = smprint("rc -lc %q", cmd);
- cmd = smprint(script, run);
- free(run);
- }
- if(fprint(fd, "%7ld\n%s", strlen(cmd), cmd) < 0)
- sysfatal("sending script: %r");
- free(cmd);
-
- /* /env/rstatus is written by the remote script to communicate exit status */
- remove("/env/rstatus");
- atexit(rcpuexit);
-
- /* Begin serving the namespace */
- exportfs(fd, fd);
-}
-
-void
-ncpu(char *host, char *cmd)
-{
- char buf[MaxStr];
- int fd;
-
- if((fd = dial(netmkaddr(host, "tcp", "ncpu"), nil, nil, nil)) < 0)
- return;
-
- /* negotiate authentication mechanism */
- strcpy(buf, "p9");
- if(ealgs != nil){
- strcat(buf, " ");
- strcat(buf, ealgs);
- }
- writestr(fd, buf, "negotiating authentication method", 0);
- if(readstr(fd, buf, sizeof buf) < 0)
- sysfatal("can't negotiate authentication method: %r");
- if(*buf)
- sysfatal("%s", buf);
-
- /* authenticate and encrypt the channel */
- fd = p9authssl(fd);
-
- /* tell remote side the command */
- if(cmd != nil){
- cmd = smprint("!%s", cmd);
- writestr(fd, cmd, "cmd", 0);
- free(cmd);
- }
-
- /* Tell the remote side where our working directory is */
- if(getcwd(buf, sizeof(buf)) == 0)
- writestr(fd, "NO", "dir", 0);
- else
- writestr(fd, buf, "dir", 0);
-
- /*
- * Wait for the other end to execute and start our file service
- * of /mnt/term
- */
- if(readstr(fd, buf, sizeof(buf)) < 0)
- sysfatal("waiting for FS: %r");
- if(strncmp("FS", buf, 2) != 0) {
- print("remote cpu: %s", buf);
- exits(buf);
- }
-
- if(readstr(fd, buf, sizeof(buf)) < 0)
- sysfatal("waiting for remote export: %r");
- if(strcmp(buf, "/") != 0){
- print("remote cpu: %s", buf);
- exits(buf);
- }
- write(fd, "OK", 2);
-
- /* Begin serving the gnot namespace */
- exportfs(fd, fd);
-}
-
-void
-usage(void)
-{
- fprint(2, "usage: %s [-9GBO] "
- "[-h host] [-u user] [-a authserver] [-s secstore] "
- "[-e 'crypt hash'] [-k keypattern] "
- "[-p] [-t timeout] "
- "[-r root] "
- "[-g geometry] "
- "[-c cmd ...]\n", argv0);
- exits("usage");
-}
-
-static char *cmd;
-
-extern void cpubody(void);
-
-void
-cpumain(int argc, char **argv)
-{
- char *s;
-
- user = getenv("USER");
- host = getenv("cpu");
- authserver = getenv("auth");
-
- ARGBEGIN{
- case '9':
- nineflag = 1;
- /* wet floor */
- case 'G':
- nogfx = 1;
- /* wet floor */
- case 'B':
- nokbd = 1;
- break;
- case 'O':
- norcpu = 1;
- break;
- case 'p':
- aanfilter = 1;
- break;
- case 't':
- aanto = (int)strtol(EARGF(usage()), nil, 0);
- break;
- case 'h':
- host = EARGF(usage());
- break;
- case 'a':
- authserver = EARGF(usage());
- break;
- case 's':
- secstore = EARGF(usage());
- break;
- case 'e':
- ealgs = EARGF(usage());
- if(*ealgs == 0 || strcmp(ealgs, "clear") == 0)
- ealgs = nil;
- break;
- case 'k':
- keyspec = EARGF(usage());
- break;
- case 'u':
- user = EARGF(usage());
- break;
- case 'r':
- s = smprint("/root/%s", EARGF(usage()));
- cleanname(s);
- if(bind(s, "/root", MREPL) < 0)
- panic("bind /root: %r");
- free(s);
- break;
- case 'c':
- cmd = estrdup(EARGF(usage()));
- while((s = ARGF()) != nil){
- char *old = cmd;
- cmd = smprint("%s %q", cmd, s);
- free(old);
- }
- break;
- case 'g':
- /* X11 geometry string
- * [=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]
- */
- geometry = EARGF(usage());
- break;
- default:
- usage();
- }ARGEND;
-
- if(argc != 0)
- usage();
-
- if(nineflag){
- exportfs(lfdfd(0), lfdfd(1));
- return;
- }
-
- if((pass = getenv("PASS")) != nil)
- remove("/env/PASS");
-
- if(!nogfx)
- guimain();
- else
- cpubody();
-}
-
-void
-cpubody(void)
-{
- char *s;
-
- if(!nogfx){
- if(bind("#i", "/dev", MBEFORE) < 0)
- panic("bind #i: %r");
- if(bind("#m", "/dev", MBEFORE) < 0)
- panic("bind #m: %r");
- if(cmd == nil)
- atexit(ending);
- }
- if(bind("/root", "/", MAFTER) < 0)
- panic("bind /root: %r");
-
- if(host == nil)
- if((host = readcons("cpu", "cpu", 0)) == nil)
- sysfatal("user terminated input");
-
- if(authserver == nil)
- if((authserver = readcons("auth", host, 0)) == nil)
- sysfatal("user terminated input");
-
- if(user == nil)
- if((user = readcons("user", "glenda", 0)) == nil)
- sysfatal("user terminated input");
-
- if(mountfactotum() < 0){
- if(secstore == nil)
- secstore = authserver;
- if(havesecstore(secstore, user)){
- s = secstorefetch(secstore, user, pass);
- if(s){
- if(strlen(s) >= sizeof secstorebuf)
- sysfatal("secstore data too big");
- strcpy(secstorebuf, s);
- }
- }
- }
-
- if(!norcpu)
- rcpu(host, cmd);
-
- ncpu(host, cmd);
-
- sysfatal("can't dial %s: %r", host);
-}
-
-void
-writestr(int fd, char *str, char *thing, int ignore)
-{
- int l, n;
-
- l = strlen(str);
- n = write(fd, str, l+1);
- if(!ignore && n < 0)
- sysfatal("writing network: %s: %r", thing);
-}
-
-int
-readstr(int fd, char *str, int len)
-{
- int n;
-
- while(len) {
- n = read(fd, str, 1);
- if(n < 0)
- return -1;
- if(n == 0){
- werrstr("hung up");
- return -1;
- }
- if(*str == '\0')
- return 0;
- str++;
- len--;
- }
- return -1;
-}
-
-static void
-mksecret(char *t, uchar *f)
-{
- sprint(t, "%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux",
- f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7], f[8], f[9]);
-}
-
-/*
- * plan9 authentication followed by rc4 encryption
- */
-static int
-p9authssl(int fd)
-{
- uchar key[16];
- uchar digest[SHA1dlen];
- char fromclientsecret[21];
- char fromserversecret[21];
- AuthInfo *ai;
-
- ai = p9any(fd);
- memset(secstorebuf, 0, sizeof(secstorebuf)); /* forget secstore secrets */
- if(ai == nil)
- sysfatal("can't authenticate: %r");
-
- if(ealgs == nil)
- return fd;
-
- if(ai->nsecret < 8){
- sysfatal("p9authssl: secret too small");
- return -1;
- }
- memmove(key+4, ai->secret, 8);
-
- /* exchange random numbers */
- genrandom(key, 4);
- if(write(fd, key, 4) != 4){
- sysfatal("p9authssl: write random: %r");
- return -1;
- }
- if(readn(fd, key+12, 4) != 4){
- sysfatal("p9authssl: read random: %r");
- return -1;
- }
-
- /* scramble into two secrets */
- sha1(key, sizeof(key), digest, nil);
- mksecret(fromclientsecret, digest);
- mksecret(fromserversecret, digest+10);
-
- /* set up encryption */
- fd = pushssl(fd, ealgs, fromclientsecret, fromserversecret, nil);
- if(fd < 0)
- sysfatal("p9authssl: pushssl: %r");
-
- return fd;
-}
-
-/*
- * p9any authentication followed by tls-psk encryption
- */
-static int
-p9authtls(int fd)
-{
- AuthInfo *ai;
- TLSconn *conn;
-
- ai = p9any(fd);
- if(ai == nil)
- sysfatal("can't authenticate: %r");
-
- conn = mallocz(sizeof(TLSconn), 1);
- conn->pskID = "p9secret";
- conn->psk = ai->secret;
- conn->psklen = ai->nsecret;
-
- fd = tlsClient(fd, conn);
- if(fd < 0)
- sysfatal("tlsClient: %r");
-
- auth_freeAI(ai);
- free(conn->sessionID);
- free(conn);
-
- return fd;
-}
-
-int
-authdial(char *net, char *dom)
-{
- return dial(netmkaddr(authserver, "tcp", "ticket"), 0, 0, 0);
-}
-
-static int
-getastickets(Authkey *key, Ticketreq *tr, uchar *y, char *tbuf, int tbuflen)
-{
- int asfd, rv;
- char *dom;
-
- dom = tr->authdom;
- asfd = authdial(nil, dom);
- if(asfd < 0)
- return -1;
- if(y != nil){
- PAKpriv p;
-
- rv = -1;
- tr->type = AuthPAK;
- if(_asrequest(asfd, tr) != 0 || write(asfd, y, PAKYLEN) != PAKYLEN)
- goto Out;
-
- authpak_new(&p, key, (uchar*)tbuf, 1);
- if(write(asfd, tbuf, PAKYLEN) != PAKYLEN)
- goto Out;
-
- if(_asrdresp(asfd, tbuf, 2*PAKYLEN) != 2*PAKYLEN)
- goto Out;
-
- memmove(y, tbuf, PAKYLEN);
- if(authpak_finish(&p, key, (uchar*)tbuf+PAKYLEN))
- goto Out;
- }
- tr->type = AuthTreq;
- rv = _asgetticket(asfd, tr, tbuf, tbuflen);
-Out:
- close(asfd);
- return rv;
-}
-
-static int
-mkservertickets(Authkey *key, Ticketreq *tr, uchar *y, char *tbuf, int tbuflen)
-{
- Ticket t;
- int ret;
-
- if(strcmp(tr->authid, tr->hostid) != 0)
- return -1;
- memset(&t, 0, sizeof(t));
- ret = 0;
- if(y != nil){
- PAKpriv p;
-
- t.form = 1;
- memmove(tbuf, y, PAKYLEN);
- authpak_new(&p, key, y, 0);
- authpak_finish(&p, key, (uchar*)tbuf);
- }
- memmove(t.chal, tr->chal, CHALLEN);
- strcpy(t.cuid, tr->uid);
- strcpy(t.suid, tr->uid);
- genrandom((uchar*)t.key, sizeof(t.key));
- t.num = AuthTc;
- ret += convT2M(&t, tbuf+ret, tbuflen-ret, key);
- t.num = AuthTs;
- ret += convT2M(&t, tbuf+ret, tbuflen-ret, key);
- memset(&t, 0, sizeof(t));
-
- return ret;
-}
-
-static int
-gettickets(Authkey *key, Ticketreq *tr, uchar *y, char *tbuf, int tbuflen)
-{
- int ret;
- ret = getastickets(key, tr, y, tbuf, tbuflen);
- if(ret > 0)
- return ret;
- return mkservertickets(key, tr, y, tbuf, tbuflen);
-}
-
-/*
- * prompt user for a key. don't care about memory leaks, runs standalone
- */
-static Attr*
-promptforkey(char *params)
-{
- char *v;
- int fd;
- Attr *a, *attr;
- char *def;
-
- fd = open("/dev/cons", ORDWR);
- if(fd < 0)
- sysfatal("opening /dev/cons: %r");
-
- attr = _parseattr(params);
- fprint(fd, "\n!Adding key:");
- for(a=attr; a; a=a->next)
- if(a->type != AttrQuery && a->name[0] != '!')
- fprint(fd, " %q=%q", a->name, a->val);
- fprint(fd, "\n");
-
- for(a=attr; a; a=a->next){
- v = a->name;
- if(a->type != AttrQuery || v[0]=='!')
- continue;
- def = nil;
- if(strcmp(v, "user") == 0)
- def = getuser();
- a->val = readcons(v, def, 0);
- if(a->val == nil)
- sysfatal("user terminated key input");
- a->type = AttrNameval;
- }
- for(a=attr; a; a=a->next){
- v = a->name;
- if(a->type != AttrQuery || v[0]!='!')
- continue;
- def = nil;
- if(strcmp(v+1, "user") == 0)
- def = getuser();
- a->val = readcons(v+1, def, 1);
- if(a->val == nil)
- sysfatal("user terminated key input");
- a->type = AttrNameval;
- }
- fprint(fd, "!\n");
- close(fd);
- return attr;
-}
-
-/*
- * send a key to the mounted factotum
- */
-static int
-sendkey(Attr *attr)
-{
- int fd, rv;
- char buf[1024];
-
- fd = open("/mnt/factotum/ctl", ORDWR);
- if(fd < 0)
- sysfatal("opening /mnt/factotum/ctl: %r");
- rv = fprint(fd, "key %A\n", attr);
- read(fd, buf, sizeof buf);
- close(fd);
- return rv;
-}
-
-int
-askuser(char *params)
-{
- Attr *attr;
-
- fmtinstall('A', _attrfmt);
-
- attr = promptforkey(params);
- if(attr == nil)
- sysfatal("no key supplied");
- if(sendkey(attr) < 0)
- sysfatal("sending key to factotum: %r");
- return 0;
-}
-
-AuthInfo*
-p9anyfactotum(int fd, int afd)
-{
- return auth_proxy(fd, askuser, "proto=p9any role=client %s", keyspec);
-}
-
-AuthInfo*
-p9any(int fd)
-{
- char buf[1024], buf2[1024], *bbuf, *p, *proto, *dom;
- uchar crand[2*NONCELEN], cchal[CHALLEN], y[PAKYLEN];
- char tbuf[2*MAXTICKETLEN+MAXAUTHENTLEN+PAKYLEN], trbuf[TICKREQLEN+PAKYLEN];
- Authkey authkey;
- Authenticator auth;
- int afd, i, n, m, v2, dp9ik;
- Ticketreq tr;
- Ticket t;
- AuthInfo *ai;
-
- if((afd = open("/mnt/factotum/ctl", ORDWR)) >= 0)
- return p9anyfactotum(fd, afd);
- werrstr("");
-
- if(readstr(fd, buf, sizeof buf) < 0)
- sysfatal("cannot read p9any negotiation: %r");
- bbuf = buf;
- v2 = 0;
- if(strncmp(buf, "v.2 ", 4) == 0){
- v2 = 1;
- bbuf += 4;
- }
- dp9ik = 0;
- proto = nil;
- while(bbuf != nil){
- if((p = strchr(bbuf, ' ')))
- *p++ = 0;
- if((dom = strchr(bbuf, '@')) == nil)
- sysfatal("bad p9any domain");
- *dom++ = 0;
- if(strcmp(bbuf, "p9sk1") == 0 || strcmp(bbuf, "dp9ik") == 0){
- proto = bbuf;
- if(strcmp(proto, "dp9ik") == 0){
- dp9ik = 1;
- break;
- }
- }
- bbuf = p;
- }
- if(proto == nil)
- sysfatal("server did not offer p9sk1 or dp9ik");
- proto = estrdup(proto);
- sprint(buf2, "%s %s", proto, dom);
- if(write(fd, buf2, strlen(buf2)+1) != strlen(buf2)+1)
- sysfatal("cannot write user/domain choice in p9any");
- if(v2){
- if(readstr(fd, buf, sizeof buf) < 0)
- sysfatal("cannot read OK in p9any: %r");
- if(memcmp(buf, "OK\0", 3) != 0)
- sysfatal("did not get OK in p9any: got %s", buf);
- }
- genrandom(crand, 2*NONCELEN);
- genrandom(cchal, CHALLEN);
- if(write(fd, cchal, CHALLEN) != CHALLEN)
- sysfatal("cannot write p9sk1 challenge: %r");
-
- n = TICKREQLEN;
- if(dp9ik)
- n += PAKYLEN;
-
- if(readn(fd, trbuf, n) != n || convM2TR(trbuf, TICKREQLEN, &tr) <= 0)
- sysfatal("cannot read ticket request in p9sk1: %r");
-
- if(!findkey(&authkey, user, tr.authdom, proto)){
-again: if(!getkey(&authkey, user, tr.authdom, proto, pass))
- sysfatal("no password");
- }
-
- strecpy(tr.hostid, tr.hostid+sizeof tr.hostid, user);
- strecpy(tr.uid, tr.uid+sizeof tr.uid, user);
-
- if(dp9ik){
- memmove(y, trbuf+TICKREQLEN, PAKYLEN);
- n = gettickets(&authkey, &tr, y, tbuf, sizeof(tbuf));
- } else {
- n = gettickets(&authkey, &tr, nil, tbuf, sizeof(tbuf));
- }
- if(n <= 0)
- sysfatal("cannot get auth tickets in p9sk1: %r");
-
- m = convM2T(tbuf, n, &t, &authkey);
- if(m <= 0 || t.num != AuthTc){
- print("?password mismatch with auth server\n");
- if(pass != nil && *pass)
- sysfatal("wrong password");
- goto again;
- }
- n -= m;
- memmove(tbuf, tbuf+m, n);
-
- if(dp9ik && write(fd, y, PAKYLEN) != PAKYLEN)
- sysfatal("cannot send authpak public key back: %r");
-
- auth.num = AuthAc;
- memmove(auth.rand, crand, NONCELEN);
- memmove(auth.chal, tr.chal, CHALLEN);
- m = convA2M(&auth, tbuf+n, sizeof(tbuf)-n, &t);
- n += m;
-
- if(write(fd, tbuf, n) != n)
- sysfatal("cannot send ticket and authenticator back: %r");
-
- if((n=readn(fd, tbuf, m)) != m || memcmp(tbuf, "cpu:", 4) == 0){
- if(n <= 4)
- sysfatal("cannot read authenticator");
-
- /*
- * didn't send back authenticator:
- * sent back fatal error message.
- */
- memmove(buf, tbuf, n);
- i = readn(fd, buf+n, sizeof buf-n-1);
- if(i > 0)
- n += i;
- buf[n] = 0;
- sysfatal("server says: %s", buf);
- }
-
- if(convM2A(tbuf, n, &auth, &t) <= 0
- || auth.num != AuthAs || tsmemcmp(auth.chal, cchal, CHALLEN) != 0){
- print("?you and auth server agree about password.\n");
- print("?server is confused.\n");
- sysfatal("server lies");
- }
- memmove(crand+NONCELEN, auth.rand, NONCELEN);
-
- // print("i am %s there.\n", t.suid);
-
- ai = mallocz(sizeof(AuthInfo), 1);
- ai->suid = estrdup(t.suid);
- ai->cuid = estrdup(t.cuid);
- if(dp9ik){
- static char info[] = "Plan 9 session secret";
- ai->nsecret = 256;
- ai->secret = mallocz(ai->nsecret, 1);
- hkdf_x( crand, 2*NONCELEN,
- (uchar*)info, sizeof(info)-1,
- (uchar*)t.key, NONCELEN,
- ai->secret, ai->nsecret,
- hmac_sha2_256, SHA2_256dlen);
- } else {
- ai->nsecret = 8;
- ai->secret = mallocz(ai->nsecret, 1);
- des56to64((uchar*)t.key, ai->secret);
- }
-
- memset(&t, 0, sizeof(t));
- memset(&auth, 0, sizeof(auth));
- memset(&authkey, 0, sizeof(authkey));
- memset(cchal, 0, sizeof(cchal));
- memset(crand, 0, sizeof(crand));
- free(proto);
-
- return ai;
-}
-
-static int
-findkey(Authkey *key, char *user, char *dom, char *proto)
-{
- char buf[8192], *f[50], *p, *ep, *nextp, *hex, *pass, *id, *role;
- int nf, haveproto, havedom, i;
-
- for(p=secstorebuf; *p; p=nextp){
- nextp = strchr(p, '\n');
- if(nextp == nil){
- ep = p+strlen(p);
- nextp = "";
- }else{
- ep = nextp++;
- }
- if(ep-p >= sizeof buf){
- print("warning: skipping long line in secstore factotum file\n");
- continue;
- }
- memmove(buf, p, ep-p);
- buf[ep-p] = 0;
- nf = tokenize(buf, f, nelem(f));
- if(nf == 0 || strcmp(f[0], "key") != 0)
- continue;
- id = pass = hex = role = nil;
- havedom = haveproto = 0;
- for(i=1; i<nf; i++){
- if(strncmp(f[i], "user=", 5) == 0)
- id = f[i]+5;
- if(strncmp(f[i], "!password=", 10) == 0)
- pass = f[i]+10;
- if(strncmp(f[i], "!hex=", 5) == 0)
- hex = f[i]+5;
- if(strncmp(f[i], "role=", 5) == 0)
- role = f[i]+5;
- if(strncmp(f[i], "dom=", 4) == 0 && strcmp(f[i]+4, dom) == 0)
- havedom = 1;
- if(strncmp(f[i], "proto=", 6) == 0 && strcmp(f[i]+6, proto) == 0)
- haveproto = 1;
- }
- if(!haveproto || !havedom)
- continue;
- if(role != nil && strcmp(role, "client") != 0)
- continue;
- if(id == nil || strcmp(user, id) != 0)
- continue;
- if(pass == nil && hex == nil)
- continue;
- if(hex != nil){
- memset(key, 0, sizeof(*key));
- if(strcmp(proto, "dp9ik") == 0) {
- if(dec16(key->aes, AESKEYLEN, hex, strlen(hex)) != AESKEYLEN)
- continue;
- } else {
- if(dec16((uchar*)key->des, DESKEYLEN, hex, strlen(hex)) != DESKEYLEN)
- continue;
- }
- } else {
- passtokey(key, pass);
- }
- if(strcmp(proto, "dp9ik") == 0)
- authpak_hash(key, user);
- memset(buf, 0, sizeof buf);
- return 1;
- }
- memset(buf, 0, sizeof buf);
- return 0;
-}
-
-static int
-getkey(Authkey *key, char *user, char *dom, char *proto, char *pass)
-{
- char buf[1024];
-
- if(pass != nil && *pass)
- pass = estrdup(pass);
- else {
- snprint(buf, sizeof buf, "%s@%s %s password", user, dom, proto);
- pass = readcons(buf, nil, 1);
- memset(buf, 0, sizeof buf);
- }
- if(pass != nil){
- snprint(secstorebuf, sizeof(secstorebuf), "key proto=%q dom=%q user=%q !password=%q\n",
- proto, dom, user, pass);
- memset(pass, 0, strlen(pass));
- free(pass);
- return findkey(key, user, dom, proto);
- }
- return 0;
-}
binary files a/drawcpu /dev/null differ
--- a/drawcpu.1
+++ /dev/null
@@ -1,239 +1,0 @@
-.TH DRAWCPU 1
-
-.SH NAME
-drawcpu \- connection to cpu, fs, and auth servers
-
-.SH SYNOPSIS
-.B drawcpu
-[
-.B -9GBO
-] [
-.B -h
-.I host
-] [
-.B -u
-.I user
-] [
-.B -a
-.I authserver
-] [
-.B -s
-.I secstore
-] [
-.B -e
-\fR'\fIcrypt hash\fR'
-] [
-.B -k
-.I keypattern
-] [
-.B -p
-] [
-.B -t
-.I timeout
-] [
-.B -r
-.I root
-] [
-.B -g
-.I geometry
-] [
-.B -c
-.I cmd \fR...]
-
-.SH DESCRIPTION
-.I Drawterm
-is a client for connecting venerable systems to Plan 9 systems. The standard behavior with no options provided is to begin a graphical session which will prompt for a cpu server, auth server, and password. If $USER is not set, drawcpu will prompt for a username as well.
-
-The goal of drawcpu is to provide an abstraction layer from the client operating system to the desired Plan 9 system. Client-side devices that can be represented as filesystems will be and are served from the namespace drawcpu operates in. Generally, this means that drawcpu behaves like a Plan 9 kernel and will attempt to reconstruct a Plan 9 terminal-like experience from a non-Plan 9 system.
-
-.PP
-The options are:
-.PD
-
-.TP
-.B -9
-Start drawcpu in 9P mode;
-exporting the namespace over 9P on standard input and output.
-Graphics and keyboard input are disabled.
-
-.TP
-.B -G
-Start drawcpu in text-only mode (no graphics).
-
-.TP
-.B -B
-Disable kbdfs.
-
-.TP
-.B -O
-Use the old
-.IR cpu (1)
-to connect to the cpu server rather than
-.IR rcpu (1)\fR.
-
-.TP
-.B -h \fIhost
-Connect to \fIhost\fR for cpu.
-
-.TP
-.B -u \fIuser
-Remote user id.
-
-.TP
-.B -a \fIauthserver
-Connect to \fIauthserver\fR for auth.
-
-.TP
-.B -s \fIsecstore
-Sets the address of the
-.IR secstore (8)
-server. If the -s option is absent,
-.IR secstore (1)
-will attempt to dial tcp!$auth!secstore (or the otherwise specified auth server).
-
-.TP
-.B -e \fR'\fIcrypt hash\fR'
-Specifies the \fR'\fIcrypt hash\fR'
-for the connection. The default is 'rc4_256 sha1'. Usage of no encryption can be specified by 'clear' as per
-.IR ssl (3)\fR. Note that this option is deprecated and only relevant to the outdated
-.IR cpu (1)
-protocol.
-
-.TP
-.B -k \fIkeypattern
-Use keypattern to select a key to authenticate to the remote side (see
-.IR auth (2)\fR).
-
-.TP
-.B -p
-Protect the connection against connection resets by establishing
-.IR aan (8)
-tunnel.
-
-.TP
-.B -t \fItimeout
-Set the timeout for
-.IR aan (8)
-to a value in
-.I seconds\fR (default is one day).
-
-.TP
-.B -r \fIroot
-Specifies the root directory on the client. The default is
-.I /root
-and all further paths are relative thereto.
-
-.TP
-.B -c \fIcmd \fR...
-The command to run can be passed with -c cmd ..., otherwise an interactive shell is started. The user's profile is run before the command with $service set to cpu to allow further customization of the environment (see
-.IR rc (1)
-for more information).
-
-.PP
-.SH ENVIRONMENT VARIABLES
-.IP USER
-Unless otherwise specified, the user stored in $USER is used for authentication.
-
-.IP PASS
-If $PASS is set, no password will be prompted for in authentication and the contents of $PASS will be used instead.
-
-.IP cpu
-Unless otherwise specified, the address stored in $cpu is used for the
-.IR rcpu (1)
-connection (if set).
-
-.IP auth
-Unless otherwise specified, the address stored in $auth is used for the
-.IR rcpu (1)
-connection (if set).
-
-.PP
-.SH SERVICES
-A number of services are provided in drawcpu. The exact functionality and availability of certain features may be dependent on your platform or architecture:
-
-.TP
-.B /mnt/term
-A mount of the client machine's root filesystem as well as certain virtual filesystems to present Plan 9 devices and interfaces that are not available on non-Plan 9 systems. On Windows this is a directory containing the available lettered disks (C:, A:, etc.). Additionally, there is always a /mnt/term/root folder which is a copy of the client machine's namespace with no virtual filesystems present as to avoid conflicting names (such as with Linux's /root).
-
-.TP
-.B #b
-Assuming the -B flag is not set, /dev/kbd will be provided for kbdfs (see
-.IR kbd (3)\fR).
-
-.TP
-.B #i
-Assuming the -G flag is not set, various drawing device files will be provided in /dev (see
-.IR draw (3)\fR).
-
-.TP
-.B #m
-Assuming the -G flag is not set, files for controlling the mouse will provided in /dev (see
-.IR mouse (3)\fR).
-
-.TP
-.B #c
-A number of console device files giving access to the console screen and miscellaneous information are provided and mounted in /dev (see
-.IR cons (3)\fR).
-
-.TP
-.B #I
-The network filesystem is served and bound over /net, providing the interface to Internet Protocol stacks (see
-.IR ip (3)\fR).
-
-.TP
-.B #A
-An audio device filesystem is served, if possible, as a one-level directory in /dev (see
-.IR audio (3)\fR).
-Note that this device, if unable to be served, will not cause a panic in drawcpu.
-
-.PP
-.SH EXAMPLES
-Make a headless rcpu session connecting to 10.30.167.25 using plan9.postnix.us as the auth server with
-.IR aan (8)
-enabled:
-.IP
-.EX
-drawcpu -G -h 10.30.167.25 -a plan9.postnix.us -p
-.EE
-.PP
-
-Make a session using cpu rather than rcpu to tenshi.postnix.us; this command is the same for connecting to a Plan 9 4th edition system:
-.IP
-.EX
-drawcpu -O -h tenshi.postnix.us
-.EE
-.PP
-
-.PP
-.SH SOURCE
-.B https://git.9front.org/plan9front/drawcpu/HEAD/info.html
-
-.PP
-.SH "SEE ALSO"
-.IR rc (1),
-.IR cpu (1),
-.IR rcpu(1),
-.IR con (1),
-.IR import (4),
-.IR exportfs (4),
-.IR tlssrv (8),
-.IR aan (8)
-
-.PP
-.SH BUGS
-Drawterm is
-.I not
-a Plan 9 program.
-
-.PP
-.SH HISTORY
-Drawterm was originally developed by Russ Cox (rsc) for Plan 9 4th edition. This original version is still usable on Plan 9 and its forks which use the p9sk1 and older
-.IR authsrv (6)
-protocols.
-.B https://swtch.com/drawcpu/
-
-The 9front project has forked drawcpu to incorporate features from 9front, most importantly dp9ik authentication support (see
-.IR authsrv (6)\fR)
-and the TLS-based
-.IR rcpu (1)
-protocol.
--- a/drawcpu.h
+++ b/drawcpu.h
@@ -1,10 +1,4 @@
-extern int havesecstore(char *addr, char *owner);
-extern char *secstore;
-extern char *secstorefetch(char *addr, char *owner, char *passwd);
-extern char *authserver;
-extern int exportfs(int, int);
extern void runcommand(int, char**);
-extern int dialfactotum(void);
extern char *getuser(void);
extern int session(void);
extern int aanclient(char*, int);
--- a/exportfs/Makefile
+++ /dev/null
@@ -1,16 +1,0 @@
-ROOT=..
-include ../Make.config
-LIB=libexportfs.a
-
-OFILES=\
- exportfs.$O\
- exportsrv.$O
-
-default: $(LIB)
-$(LIB): $(OFILES)
- $(AR) r $(LIB) $(OFILES)
- $(RANLIB) $(LIB)
-
-%.$O: %.c
- $(CC) $(CFLAGS) $*.c
-
--- a/exportfs/exportfs.c
+++ /dev/null
@@ -1,504 +1,0 @@
-/*
- * exportfs - Export a plan 9 name space across a network
- */
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-#include <libsec.h>
-#include "drawcpu.h"
-#define Extern
-#include "exportfs.h"
-
-#define QIDPATH ((((vlong)1)<<48)-1)
-vlong newqid = 0;
-
-void (*fcalls[256])(Fsrpc*);
-
-/* accounting and debugging counters */
-int filecnt;
-int freecnt;
-int qidcnt;
-int qfreecnt;
-int ncollision;
-int netfd[2];
-
-int
-exportfs(int rfd, int wfd)
-{
- char buf[ERRMAX], ebuf[ERRMAX];
- Fsrpc *r;
- int i, n;
-
-
- fcalls[Tversion] = Xversion;
- fcalls[Tauth] = Xauth;
- fcalls[Tflush] = Xflush;
- fcalls[Tattach] = Xattach;
- fcalls[Twalk] = Xwalk;
- fcalls[Topen] = slave;
- fcalls[Tcreate] = Xcreate;
- fcalls[Tclunk] = Xclunk;
- fcalls[Tread] = slave;
- fcalls[Twrite] = slave;
- fcalls[Tremove] = Xremove;
- fcalls[Tstat] = Xstat;
- fcalls[Twstat] = Xwstat;
-
- srvfd = -1;
- netfd[0] = rfd;
- netfd[1] = wfd;
-
- strcpy(buf, "this is buf");
- strcpy(ebuf, "this is ebuf");
- DEBUG(DFD, "exportfs: started\n");
-
- messagesize = iounit(rfd);
- if(messagesize == 0)
- messagesize = IOUNIT+IOHDRSZ;
-
- Workq = emallocz(sizeof(Fsrpc)*Nr_workbufs);
- fhash = emallocz(sizeof(Fid*)*FHASHSIZE);
-
- fmtinstall('F', fcallfmt);
-
- initroot();
-
- DEBUG(DFD, "exportfs: %s\n", buf);
-
- /*
- * Start serving file requests from the network
- */
- for(;;) {
- r = getsbuf();
- if(r == 0)
- fatal("Out of service buffers");
-
- DEBUG(DFD, "read9p...");
- n = read9pmsg(netfd[0], r->buf, messagesize);
- if(n <= 0)
- fatal(nil);
-
- if(convM2S(r->buf, n, &r->work) == 0){
- iprint("convM2S %d byte message\n", n);
- for(i=0; i<n; i++){
- iprint(" %.2ux", r->buf[i]);
- if(i%16 == 15)
- iprint("\n");
- }
- if(i%16)
- iprint("\n");
- fatal("convM2S format error");
- }
-
-if(0) iprint("<- %F\n", &r->work);
- DEBUG(DFD, "%F\n", &r->work);
- (fcalls[r->work.type])(r);
- }
-}
-
-void
-reply(Fcall *r, Fcall *t, char *err)
-{
- uchar *data;
- int m, n;
-
- t->tag = r->tag;
- t->fid = r->fid;
- if(err) {
- t->type = Rerror;
- t->ename = err;
- }
- else
- t->type = r->type + 1;
-
-if(0) iprint("-> %F\n", t);
- DEBUG(DFD, "\t%F\n", t);
-
- data = malloc(messagesize); /* not mallocz; no need to clear */
- if(data == nil)
- fatal(Enomem);
- n = convS2M(t, data, messagesize);
- if((m=write(netfd[1], data, n))!=n){
- iprint("wrote %d got %d (%r)\n", n, m);
- fatal("write");
- }
- free(data);
-}
-
-Fid *
-getfid(int nr)
-{
- Fid *f;
-
- for(f = fidhash(nr); f; f = f->next)
- if(f->nr == nr)
- return f;
-
- return 0;
-}
-
-int
-freefid(int nr)
-{
- Fid *f, **l;
- char buf[128];
-
- l = &fidhash(nr);
- for(f = *l; f; f = f->next) {
- if(f->nr == nr) {
- if(f->mid) {
- sprint(buf, "/mnt/exportfs/%d", f->mid);
- unmount(0, buf);
- psmap[f->mid] = 0;
- }
- if(f->f) {
- freefile(f->f);
- f->f = nil;
- }
- *l = f->next;
- f->next = fidfree;
- fidfree = f;
- return 1;
- }
- l = &f->next;
- }
-
- return 0;
-}
-
-Fid *
-newfid(int nr)
-{
- Fid *new, **l;
- int i;
-
- l = &fidhash(nr);
- for(new = *l; new; new = new->next)
- if(new->nr == nr)
- return 0;
-
- if(fidfree == 0) {
- fidfree = emallocz(sizeof(Fid) * Fidchunk);
-
- for(i = 0; i < Fidchunk-1; i++)
- fidfree[i].next = &fidfree[i+1];
-
- fidfree[Fidchunk-1].next = 0;
- }
-
- new = fidfree;
- fidfree = new->next;
-
- memset(new, 0, sizeof(Fid));
- new->next = *l;
- *l = new;
- new->nr = nr;
- new->fid = -1;
- new->mid = 0;
-
- return new;
-}
-
-Fsrpc *
-getsbuf(void)
-{
- static int ap;
- int look, rounds;
- Fsrpc *wb;
- int small_instead_of_fast = 1;
-
- if(small_instead_of_fast)
- ap = 0; /* so we always start looking at the beginning and reuse buffers */
-
- for(rounds = 0; rounds < 10; rounds++) {
- for(look = 0; look < Nr_workbufs; look++) {
- if(++ap == Nr_workbufs)
- ap = 0;
- if(Workq[ap].busy == 0)
- break;
- }
-
- if(look == Nr_workbufs){
- sleep(10 * rounds);
- continue;
- }
-
- wb = &Workq[ap];
- wb->pid = 0;
- wb->canint = 0;
- wb->flushtag = NOTAG;
- wb->busy = 1;
- if(wb->buf == nil) /* allocate buffers dynamically to keep size down */
- wb->buf = emallocz(messagesize);
- return wb;
- }
- fatal("No more work buffers");
- return nil;
-}
-
-void
-freefile(File *f)
-{
- File *parent, *child;
-
-Loop:
- f->ref--;
- if(f->ref > 0)
- return;
- freecnt++;
- if(f->ref < 0) abort();
- DEBUG(DFD, "free %s\n", f->name);
- /* delete from parent */
- parent = f->parent;
- if(parent->child == f)
- parent->child = f->childlist;
- else{
- for(child=parent->child; child->childlist!=f; child=child->childlist)
- if(child->childlist == nil)
- fatal("bad child list");
- child->childlist = f->childlist;
- }
- freeqid(f->qidt);
- free(f->name);
- f->name = nil;
- free(f);
- f = parent;
- if(f != nil)
- goto Loop;
-}
-
-File *
-file(File *parent, char *name)
-{
- Dir *dir;
- char *path;
- File *f;
-
- DEBUG(DFD, "\tfile: 0x%p %s name %s\n", parent, parent->name, name);
-
- path = makepath(parent, name);
- dir = dirstat(path);
- free(path);
- if(dir == nil)
- return nil;
-
- for(f = parent->child; f; f = f->childlist)
- if(strcmp(name, f->name) == 0)
- break;
-
- if(f == nil){
- f = emallocz(sizeof(File));
- f->name = estrdup(name);
-
- f->parent = parent;
- f->childlist = parent->child;
- parent->child = f;
- parent->ref++;
- f->ref = 0;
- filecnt++;
- }
- f->ref++;
- f->qid.type = dir->qid.type;
- f->qid.vers = dir->qid.vers;
- f->qidt = uniqueqid(dir);
- f->qid.path = f->qidt->uniqpath;
-
- f->inval = 0;
-
- free(dir);
-
- return f;
-}
-
-void
-initroot(void)
-{
- Dir *dir;
-
- root = emallocz(sizeof(File));
- root->name = estrdup(".");
-
- dir = dirstat(root->name);
- if(dir == nil)
- fatal("root stat");
-
- root->ref = 1;
- root->qid.vers = dir->qid.vers;
- root->qidt = uniqueqid(dir);
- root->qid.path = root->qidt->uniqpath;
- root->qid.type = QTDIR;
- free(dir);
-
- psmpt = emallocz(sizeof(File));
- psmpt->name = estrdup("/");
-
- dir = dirstat(psmpt->name);
- if(dir == nil)
- return;
-
- psmpt->ref = 1;
- psmpt->qid.vers = dir->qid.vers;
- psmpt->qidt = uniqueqid(dir);
- psmpt->qid.path = psmpt->qidt->uniqpath;
- free(dir);
-
- psmpt = file(psmpt, "mnt");
- if(psmpt == 0)
- return;
- psmpt = file(psmpt, "exportfs");
-}
-
-char*
-makepath(File *p, char *name)
-{
- int i, n;
- char *c, *s, *path, *seg[256];
-
- seg[0] = name;
- n = strlen(name)+2;
- for(i = 1; i < 256 && p; i++, p = p->parent){
- seg[i] = p->name;
- n += strlen(p->name)+1;
- }
- path = malloc(n);
- if(path == nil)
- fatal("out of memory");
- s = path;
-
- while(i--) {
- for(c = seg[i]; *c; c++)
- *s++ = *c;
- *s++ = '/';
- }
- while(s[-1] == '/')
- s--;
- *s = '\0';
-
- return path;
-}
-
-int
-qidhash(vlong path)
-{
- int h, n;
-
- h = 0;
- for(n=0; n<64; n+=Nqidbits){
- h ^= path;
- path >>= Nqidbits;
- }
- return h & (Nqidtab-1);
-}
-
-void
-freeqid(Qidtab *q)
-{
- ulong h;
- Qidtab *l;
-
- q->ref--;
- if(q->ref > 0)
- return;
- qfreecnt++;
- h = qidhash(q->path);
- if(qidtab[h] == q)
- qidtab[h] = q->next;
- else{
- for(l=qidtab[h]; l->next!=q; l=l->next)
- if(l->next == nil)
- fatal("bad qid list");
- l->next = q->next;
- }
- free(q);
-}
-
-Qidtab*
-qidlookup(Dir *d)
-{
- ulong h;
- Qidtab *q;
-
- h = qidhash(d->qid.path);
- for(q=qidtab[h]; q!=nil; q=q->next)
- if(q->type==d->type && q->dev==d->dev && q->path==d->qid.path)
- return q;
- return nil;
-}
-
-int
-qidexists(vlong path)
-{
- int h;
- Qidtab *q;
-
- for(h=0; h<Nqidtab; h++)
- for(q=qidtab[h]; q!=nil; q=q->next)
- if(q->uniqpath == path)
- return 1;
- return 0;
-}
-
-Qidtab*
-uniqueqid(Dir *d)
-{
- ulong h;
- vlong path;
- Qidtab *q;
-
- q = qidlookup(d);
- if(q != nil){
- q->ref++;
- return q;
- }
- path = d->qid.path;
- while(qidexists(path)){
- DEBUG(DFD, "collision on %s\n", d->name);
- /* collision: find a new one */
- ncollision++;
- path &= QIDPATH;
- ++newqid;
- if(newqid >= (1<<16)){
- DEBUG(DFD, "collision wraparound\n");
- newqid = 1;
- }
- path |= newqid<<48;
- DEBUG(DFD, "assign qid %.16llux\n", path);
- }
- q = mallocz(sizeof(Qidtab), 1);
- if(q == nil)
- fatal("no memory for qid table");
- qidcnt++;
- q->ref = 1;
- q->type = d->type;
- q->dev = d->dev;
- q->path = d->qid.path;
- q->uniqpath = path;
- h = qidhash(d->qid.path);
- q->next = qidtab[h];
- qidtab[h] = q;
- return q;
-}
-
-void
-fatal(char *s, ...)
-{
- char buf[ERRMAX];
- va_list arg;
-
- if (s != nil) {
- va_start(arg, s);
- vsnprint(buf, ERRMAX, s, arg);
- va_end(arg);
- }
-
- /* Clear away the slave children */
-// for(m = Proclist; m; m = m->next)
-// postnote(PNPROC, m->pid, "kill");
-
- if (s != nil) {
- DEBUG(DFD, "%s\n", buf);
- sysfatal("%s", buf);
- } else
- exits(nil);
-}
-
--- a/exportfs/exportfs.h
+++ /dev/null
@@ -1,148 +1,0 @@
-/*
- * exportfs.h - definitions for exporting file server
- */
-
-#define DEBUG if(!dbg){}else fprint
-#define DFD 2
-#define fidhash(s) fhash[s%FHASHSIZE]
-
-#define Proc Exproc
-
-
-typedef struct Fsrpc Fsrpc;
-typedef struct Fid Fid;
-typedef struct File File;
-typedef struct Proc Proc;
-typedef struct Qidtab Qidtab;
-
-struct Fsrpc
-{
- int busy; /* Work buffer has pending rpc to service */
- int pid; /* Pid of slave process executing the rpc */
- int canint; /* Interrupt gate */
- int flushtag; /* Tag on which to reply to flush */
- Fcall work; /* Plan 9 incoming Fcall */
- uchar *buf; /* Data buffer */
-};
-
-struct Fid
-{
- int fid; /* system fd for i/o */
- File *f; /* File attached to this fid */
- int mode;
- int nr; /* fid number */
- int mid; /* Mount id */
- Fid *next; /* hash link */
-};
-
-struct File
-{
- char *name;
- int ref;
- Qid qid;
- Qidtab *qidt;
- int inval;
- File *parent;
- File *child;
- File *childlist;
-};
-
-struct Proc
-{
- int pid;
- int busy;
- Proc *next;
-};
-
-struct Qidtab
-{
- int ref;
- int type;
- int dev;
- vlong path;
- vlong uniqpath;
- Qidtab *next;
-};
-
-enum
-{
- MAXPROC = 50,
- FHASHSIZE = 64,
- Nr_workbufs = 50,
- Fidchunk = 1000,
- Npsmpt = 32,
- Nqidbits = 5,
- Nqidtab = (1<<Nqidbits),
-};
-
-#define Enomem Exenomem
-#define Ebadfix Exebadfid
-#define Enotdir Exenotdir
-#define Edupfid Exedupfid
-#define Eopen Exeopen
-#define Exmnt Exexmnt
-#define Emip Exemip
-#define Enopsmt Exenopsmt
-
-extern char Ebadfid[];
-extern char Enotdir[];
-extern char Edupfid[];
-extern char Eopen[];
-extern char Exmnt[];
-extern char Enomem[];
-extern char Emip[];
-extern char Enopsmt[];
-
-Extern Fsrpc *Workq;
-Extern int dbg;
-Extern File *root;
-Extern File *psmpt;
-Extern Fid **fhash;
-Extern Fid *fidfree;
-Extern Proc *Proclist;
-Extern char psmap[Npsmpt];
-Extern Qidtab *qidtab[Nqidtab];
-Extern ulong messagesize;
-Extern int srvfd;
-
-/* File system protocol service procedures */
-void Xattach(Fsrpc*);
-void Xauth(Fsrpc*);
-void Xclunk(Fsrpc*);
-void Xcreate(Fsrpc*);
-void Xflush(Fsrpc*);
-void Xnop(Fsrpc*);
-void Xremove(Fsrpc*);
-void Xstat(Fsrpc*);
-void Xversion(Fsrpc*);
-void Xwalk(Fsrpc*);
-void Xwstat(Fsrpc*);
-void slave(Fsrpc*);
-
-void reply(Fcall*, Fcall*, char*);
-Fid *getfid(int);
-int freefid(int);
-Fid *newfid(int);
-Fsrpc *getsbuf(void);
-void initroot(void);
-void fatal(char*, ...);
-char* makepath(File*, char*);
-File *file(File*, char*);
-void freefile(File*);
-void slaveopen(Fsrpc*);
-void slaveread(Fsrpc*);
-void slavewrite(Fsrpc*);
-void blockingslave(void*);
-void reopen(Fid *f);
-void noteproc(int, char*);
-void flushaction(void*, char*);
-void pushfcall(char*);
-Qidtab* uniqueqid(Dir*);
-void freeqid(Qidtab*);
-char* estrdup(char*);
-void* emallocz(uint);
-int readmessage(int, char*, int);
-
-#define notify(x)
-#define noted(x)
-
--- a/exportfs/exportsrv.c
+++ /dev/null
@@ -1,671 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-#define Extern extern
-#include "exportfs.h"
-
-char Ebadfid[] = "Bad fid";
-char Enotdir[] = "Not a directory";
-char Edupfid[] = "Fid already in use";
-char Eopen[] = "Fid already opened";
-char Exmnt[] = "Cannot .. past mount point";
-char Emip[] = "Mount in progress";
-char Enopsmt[] = "Out of pseudo mount points";
-char Enomem[] = "No memory";
-char Eversion[] = "Bad 9P2000 version";
-
-void*
-emallocz(uint n)
-{
- void *v;
-
- v = mallocz(n, 1);
- if(v == nil)
- panic("out of memory");
- return v;
-}
-
-
-void
-Xversion(Fsrpc *t)
-{
- Fcall rhdr;
-
- if(t->work.msize > messagesize)
- t->work.msize = messagesize;
- messagesize = t->work.msize;
- if(strncmp(t->work.version, "9P2000", 6) != 0){
- reply(&t->work, &rhdr, Eversion);
- return;
- }
- rhdr.version = "9P2000";
- rhdr.msize = t->work.msize;
- reply(&t->work, &rhdr, 0);
- t->busy = 0;
-}
-
-void
-Xauth(Fsrpc *t)
-{
- Fcall rhdr;
-
- reply(&t->work, &rhdr, "exportfs: authentication not required");
- t->busy = 0;
-}
-
-void
-Xflush(Fsrpc *t)
-{
- Fsrpc *w, *e;
- Fcall rhdr;
-
- e = &Workq[Nr_workbufs];
-
- for(w = Workq; w < e; w++) {
- if(w->work.tag == t->work.oldtag) {
- DEBUG(DFD, "\tQ busy %d pid %d can %d\n", w->busy, w->pid, w->canint);
- if(w->busy && w->pid) {
- w->flushtag = t->work.tag;
- DEBUG(DFD, "\tset flushtag %d\n", t->work.tag);
- // if(w->canint)
- // postnote(PNPROC, w->pid, "flush");
- t->busy = 0;
- return;
- }
- }
- }
-
- reply(&t->work, &rhdr, 0);
- DEBUG(DFD, "\tflush reply\n");
- t->busy = 0;
-}
-
-void
-Xattach(Fsrpc *t)
-{
- Fcall rhdr;
- Fid *f;
-
- f = newfid(t->work.fid);
- if(f == 0) {
- reply(&t->work, &rhdr, Ebadfid);
- t->busy = 0;
- return;
- }
-
- if(srvfd >= 0){
-/*
- if(psmpt == 0){
- Nomount:
- reply(&t->work, &rhdr, Enopsmt);
- t->busy = 0;
- freefid(t->work.fid);
- return;
- }
- for(i=0; i<Npsmpt; i++)
- if(psmap[i] == 0)
- break;
- if(i >= Npsmpt)
- goto Nomount;
- sprint(buf, "%d", i);
- f->f = file(psmpt, buf);
- if(f->f == nil)
- goto Nomount;
- sprint(buf, "/mnt/exportfs/%d", i);
- nfd = dup(srvfd, -1);
- if(amount(nfd, buf, MREPL|MCREATE, t->work.aname) < 0){
- errstr(buf, sizeof buf);
- reply(&t->work, &rhdr, buf);
- t->busy = 0;
- freefid(t->work.fid);
- close(nfd);
- return;
- }
- psmap[i] = 1;
- f->mid = i;
-*/
- }else{
- f->f = root;
- f->f->ref++;
- }
-
- rhdr.qid = f->f->qid;
- reply(&t->work, &rhdr, 0);
- t->busy = 0;
-}
-
-Fid*
-clonefid(Fid *f, int new)
-{
- Fid *n;
-
- n = newfid(new);
- if(n == 0) {
- n = getfid(new);
- if(n == 0)
- fatal("inconsistent fids");
- if(n->fid >= 0)
- close(n->fid);
- freefid(new);
- n = newfid(new);
- if(n == 0)
- fatal("inconsistent fids2");
- }
- n->f = f->f;
- n->f->ref++;
- return n;
-}
-
-void
-Xwalk(Fsrpc *t)
-{
- char err[ERRMAX], *e;
- Fcall rhdr;
- Fid *f, *nf;
- File *wf;
- int i;
-
- f = getfid(t->work.fid);
- if(f == 0) {
- reply(&t->work, &rhdr, Ebadfid);
- t->busy = 0;
- return;
- }
-
- nf = nil;
- if(t->work.newfid != t->work.fid){
- nf = clonefid(f, t->work.newfid);
- f = nf;
- }
-
- rhdr.nwqid = 0;
- e = nil;
- for(i=0; i<t->work.nwname; i++){
- if(i == MAXWELEM){
- e = "Too many path elements";
- break;
- }
-
- if(strcmp(t->work.wname[i], "..") == 0) {
- if(f->f->parent == nil) {
- e = Exmnt;
- break;
- }
- wf = f->f->parent;
- wf->ref++;
- goto Accept;
- }
-
- wf = file(f->f, t->work.wname[i]);
- if(wf == 0){
- errstr(err, sizeof err);
- e = err;
- break;
- }
- Accept:
- freefile(f->f);
- rhdr.wqid[rhdr.nwqid++] = wf->qid;
- f->f = wf;
- continue;
- }
-
- if(nf!=nil && (e!=nil || rhdr.nwqid!=t->work.nwname))
- freefid(t->work.newfid);
- if(rhdr.nwqid > 0)
- e = nil;
- reply(&t->work, &rhdr, e);
- t->busy = 0;
-}
-
-void
-Xclunk(Fsrpc *t)
-{
- Fcall rhdr;
- Fid *f;
-
- f = getfid(t->work.fid);
- if(f == 0) {
- reply(&t->work, &rhdr, Ebadfid);
- t->busy = 0;
- return;
- }
-
- if(f->fid >= 0)
- close(f->fid);
-
- freefid(t->work.fid);
- reply(&t->work, &rhdr, 0);
- t->busy = 0;
-}
-
-void
-Xstat(Fsrpc *t)
-{
- char err[ERRMAX], *path;
- Fcall rhdr;
- Fid *f;
- Dir *d;
- int s;
- uchar *statbuf;
-
- f = getfid(t->work.fid);
- if(f == 0) {
- reply(&t->work, &rhdr, Ebadfid);
- t->busy = 0;
- return;
- }
- if(f->fid >= 0)
- d = dirfstat(f->fid);
- else {
- path = makepath(f->f, "");
- d = dirstat(path);
- free(path);
- }
-
- if(d == nil) {
- errstr(err, sizeof err);
- reply(&t->work, &rhdr, err);
- t->busy = 0;
- return;
- }
-
- d->qid.path = f->f->qidt->uniqpath;
- s = sizeD2M(d);
- statbuf = emallocz(s);
- s = convD2M(d, statbuf, s);
- free(d);
- rhdr.nstat = s;
- rhdr.stat = statbuf;
- reply(&t->work, &rhdr, 0);
- free(statbuf);
- t->busy = 0;
-}
-
-static int
-getiounit(int fd)
-{
- int n;
-
- n = iounit(fd);
- if(n > messagesize-IOHDRSZ)
- n = messagesize-IOHDRSZ;
- return n;
-}
-
-void
-Xcreate(Fsrpc *t)
-{
- char err[ERRMAX], *path;
- Fcall rhdr;
- Fid *f;
- File *nf;
-
- f = getfid(t->work.fid);
- if(f == 0) {
- reply(&t->work, &rhdr, Ebadfid);
- t->busy = 0;
- return;
- }
-
-
- path = makepath(f->f, t->work.name);
- f->fid = create(path, t->work.mode, t->work.perm);
- free(path);
- if(f->fid < 0) {
- errstr(err, sizeof err);
- reply(&t->work, &rhdr, err);
- t->busy = 0;
- return;
- }
-
- nf = file(f->f, t->work.name);
- if(nf == 0) {
- errstr(err, sizeof err);
- reply(&t->work, &rhdr, err);
- t->busy = 0;
- return;
- }
-
- f->mode = t->work.mode;
- freefile(f->f);
- f->f = nf;
- rhdr.qid = f->f->qid;
- rhdr.iounit = getiounit(f->fid);
- reply(&t->work, &rhdr, 0);
- t->busy = 0;
-}
-
-void
-Xremove(Fsrpc *t)
-{
- char err[ERRMAX], *path;
- Fcall rhdr;
- Fid *f;
-
- f = getfid(t->work.fid);
- if(f == 0) {
- reply(&t->work, &rhdr, Ebadfid);
- t->busy = 0;
- return;
- }
-
- path = makepath(f->f, "");
- DEBUG(DFD, "\tremove: %s\n", path);
- if(remove(path) < 0) {
- free(path);
- errstr(err, sizeof err);
- reply(&t->work, &rhdr, err);
- t->busy = 0;
- return;
- }
- free(path);
-
- f->f->inval = 1;
- if(f->fid >= 0)
- close(f->fid);
- freefid(t->work.fid);
-
- reply(&t->work, &rhdr, 0);
- t->busy = 0;
-}
-
-void
-Xwstat(Fsrpc *t)
-{
- char err[ERRMAX], *path;
- Fcall rhdr;
- Fid *f;
- int s;
- char *strings;
- Dir d;
-
- f = getfid(t->work.fid);
- if(f == 0) {
- reply(&t->work, &rhdr, Ebadfid);
- t->busy = 0;
- return;
- }
- strings = emallocz(t->work.nstat); /* ample */
- if(convM2D(t->work.stat, t->work.nstat, &d, strings) <= BIT16SZ){
- rerrstr(err, sizeof err);
- reply(&t->work, &rhdr, err);
- t->busy = 0;
- free(strings);
- return;
- }
-
- if(f->fid >= 0)
- s = dirfwstat(f->fid, &d);
- else {
- path = makepath(f->f, "");
- s = dirwstat(path, &d);
- free(path);
- }
- if(s < 0) {
- rerrstr(err, sizeof err);
- reply(&t->work, &rhdr, err);
- }
- else {
- /* wstat may really be rename */
- if(strcmp(d.name, f->f->name)!=0 && strcmp(d.name, "")!=0){
- free(f->f->name);
- f->f->name = estrdup(d.name);
- }
- reply(&t->work, &rhdr, 0);
- }
- free(strings);
- t->busy = 0;
-}
-
-void
-slave(Fsrpc *f)
-{
- Proc *p;
- int pid;
- static int nproc;
-
- for(;;) {
- for(p = Proclist; p; p = p->next) {
- if(p->busy == 0) {
- f->pid = p->pid;
- p->busy = 1;
- pid = (uintptr)rendezvous((void*)(uintptr)p->pid, f);
- if(pid != p->pid)
- fatal("rendezvous sync fail");
- return;
- }
- }
-
- if(++nproc > MAXPROC)
- fatal("too many procs");
-
- pid = kproc("slave", blockingslave, nil);
- DEBUG(DFD, "slave pid %d\n", pid);
- if(pid == -1)
- fatal("kproc");
-
- p = malloc(sizeof(Proc));
- if(p == 0)
- fatal("out of memory");
-
- p->busy = 0;
- p->pid = pid;
- p->next = Proclist;
- Proclist = p;
-
-DEBUG(DFD, "parent %d rendez\n", pid);
- rendezvous((void*)(uintptr)pid, p);
-DEBUG(DFD, "parent %d went\n", pid);
- }
-}
-
-void
-blockingslave(void *x)
-{
- Fsrpc *p;
- Fcall rhdr;
- Proc *m;
- int pid;
-
- USED(x);
-
- notify(flushaction);
-
- pid = getpid();
-
-DEBUG(DFD, "blockingslave %d rendez\n", pid);
- m = (Proc*)rendezvous((void*)(uintptr)pid, 0);
-DEBUG(DFD, "blockingslave %d rendez got %p\n", pid, m);
-
- for(;;) {
- p = rendezvous((void*)(uintptr)pid, (void*)(uintptr)pid);
- if((uintptr)p == ~(uintptr)0) /* Interrupted */
- continue;
-
- DEBUG(DFD, "\tslave: %d %F b %d p %d\n", pid, &p->work, p->busy, p->pid);
- if(p->flushtag != NOTAG)
- goto flushme;
-
- switch(p->work.type) {
- case Tread:
- slaveread(p);
- break;
-
- case Twrite:
- slavewrite(p);
- break;
-
- case Topen:
- slaveopen(p);
- break;
-
- default:
- reply(&p->work, &rhdr, "exportfs: slave type error");
- }
- if(p->flushtag != NOTAG) {
-flushme:
- p->work.type = Tflush;
- p->work.tag = p->flushtag;
- reply(&p->work, &rhdr, 0);
- }
- p->busy = 0;
- m->busy = 0;
- }
-}
-
-int
-openmount(int sfd)
-{
- werrstr("openmount not implemented");
- return -1;
-}
-
-void
-slaveopen(Fsrpc *p)
-{
- char err[ERRMAX], *path;
- Fcall *work, rhdr;
- Fid *f;
- Dir *d;
-
- work = &p->work;
-
- f = getfid(work->fid);
- if(f == 0) {
- reply(work, &rhdr, Ebadfid);
- return;
- }
- if(f->fid >= 0) {
- close(f->fid);
- f->fid = -1;
- }
-
- path = makepath(f->f, "");
- DEBUG(DFD, "\topen: %s %d\n", path, work->mode);
-
- p->canint = 1;
- if(p->flushtag != NOTAG){
- free(path);
- return;
- }
- /* There is a race here I ignore because there are no locks */
- f->fid = open(path, work->mode);
- free(path);
- p->canint = 0;
- if(f->fid < 0 || (d = dirfstat(f->fid)) == nil) {
- Error:
- errstr(err, sizeof err);
- reply(work, &rhdr, err);
- return;
- }
- f->f->qid = d->qid;
- free(d);
- if(f->f->qid.type & QTMOUNT){ /* fork new exportfs for this */
- f->fid = openmount(f->fid);
- if(f->fid < 0)
- goto Error;
- }
-
- DEBUG(DFD, "\topen: fd %d\n", f->fid);
- f->mode = work->mode;
- rhdr.iounit = getiounit(f->fid);
- rhdr.qid = f->f->qid;
- reply(work, &rhdr, 0);
-}
-
-void
-slaveread(Fsrpc *p)
-{
- Fid *f;
- int n, r;
- Fcall *work, rhdr;
- char *data, err[ERRMAX];
-
- work = &p->work;
-
- f = getfid(work->fid);
- if(f == 0) {
- reply(work, &rhdr, Ebadfid);
- return;
- }
-
- n = (work->count > messagesize-IOHDRSZ) ? messagesize-IOHDRSZ : work->count;
- p->canint = 1;
- if(p->flushtag != NOTAG)
- return;
- data = malloc(n);
- if(data == nil)
- fatal(Enomem);
-
- /* can't just call pread, since directories must update the offset */
- r = pread(f->fid, data, n, work->offset);
- p->canint = 0;
- if(r < 0) {
- free(data);
- errstr(err, sizeof err);
- reply(work, &rhdr, err);
- return;
- }
-
- DEBUG(DFD, "\tread: fd=%d %d bytes\n", f->fid, r);
-
- rhdr.data = data;
- rhdr.count = r;
- reply(work, &rhdr, 0);
- free(data);
-}
-
-void
-slavewrite(Fsrpc *p)
-{
- char err[ERRMAX];
- Fcall *work, rhdr;
- Fid *f;
- int n;
-
- work = &p->work;
-
- f = getfid(work->fid);
- if(f == 0) {
- reply(work, &rhdr, Ebadfid);
- return;
- }
-
- n = (work->count > messagesize-IOHDRSZ) ? messagesize-IOHDRSZ : work->count;
- p->canint = 1;
- if(p->flushtag != NOTAG)
- return;
- n = pwrite(f->fid, work->data, n, work->offset);
- p->canint = 0;
- if(n < 0) {
- errstr(err, sizeof err);
- reply(work, &rhdr, err);
- return;
- }
-
- DEBUG(DFD, "\twrite: %d bytes fd=%d\n", n, f->fid);
-
- rhdr.count = n;
- reply(work, &rhdr, 0);
-}
-
-void
-reopen(Fid *f)
-{
- USED(f);
- fatal("reopen");
-}
-
-void
-flushaction(void *a, char *cause)
-{
- USED(a);
- if(strncmp(cause, "sys:", 4) == 0 && !strstr(cause, "pipe")) {
- fprint(2, "exportsrv: note: %s\n", cause);
- exits("noted");
- }
- if(strncmp(cause, "kill", 4) == 0)
- noted(NDFLT);
-
- noted(NCONT);
-}
--- /dev/null
+++ b/getuser.c
@@ -1,0 +1,17 @@
+#include <u.h>
+#include <pwd.h>
+#include <libc.h>
+#include "drawcpu.h"
+
+char*
+getuser(void)
+{
+ static char user[64];
+ struct passwd *pw;
+
+ pw = getpwuid(getuid());
+ if(pw == nil)
+ return "none";
+ strecpy(user, user+sizeof user, pw->pw_name);
+ return user;
+}
--- a/gui-cocoa/screen.m
+++ b/gui-cocoa/screen.m
@@ -71,6 +71,7 @@
void
screeninit(void)
{
+ /*
memimageinit();
NSSize s = [myview convertSizeToBacking:myview.frame.size];
screensize(Rect(0, 0, s.width, s.height), ARGB32);
@@ -79,6 +80,7 @@
terminit();
readybit = 1;
wakeup(&rend);
+ */
}
void
@@ -201,6 +203,7 @@
void
setcursor(void)
{
+ /*
static unsigned char data[64], data2[256];
unsigned char *planes[2] = {&data[0], &data[32]};
unsigned char *planes2[2] = {&data2[0], &data2[128]};
@@ -274,11 +277,13 @@
dispatch_async(dispatch_get_main_queue(), ^(void){
[[myview window] invalidateCursorRectsForView:myview];
});
+ */
}
void
mouseset(Point p)
{
+ /*
dispatch_async(dispatch_get_main_queue(), ^(void){@autoreleasepool{
NSPoint s;
@@ -297,6 +302,7 @@
CGAssociateMouseAndMouseCursorPosition(true);
}
}});
+ */
}
@implementation AppDelegate
@@ -376,9 +382,11 @@
- (void) windowDidBecomeKey:(id)arg
{
+ /*
NSPoint p;
p = [_window convertPointToBacking:[_window mouseLocationOutsideOfEventStream]];
absmousetrack(p.x, [myview convertSizeToBacking:myview.frame.size].height - p.y, 0, ticks());
+ */
}
- (void) windowDidResignKey:(id)arg
@@ -525,6 +533,7 @@
}
- (void)flagsChanged:(NSEvent*)event {
+ /*
NSEventModifierFlags x;
NSUInteger u;
@@ -571,9 +580,11 @@
if((~x & _mods & NSEventModifierFlagCapsLock) != 0)
kbdkey(Kcaps, 0);
_mods = x;
+ */
}
- (void) clearMods {
+ /*
if((_mods & NSEventModifierFlagShift) != 0){
kbdkey(Kshift, 0);
_mods ^= NSEventModifierFlagShift;
@@ -586,10 +597,12 @@
kbdkey(Kalt, 0);
_mods ^= NSEventModifierFlagOption;
}
+ */
}
- (void) mouseevent:(NSEvent*)event
{
+ /*
NSPoint p;
Point q;
NSUInteger u;
@@ -609,16 +622,19 @@
}else if(m & NSEventModifierFlagCommand)
u = 4;
}
- absmousetrack(p.x, [self convertSizeToBacking:self.frame.size].height - p.y, u, ticks());
+ //absmousetrack(p.x, [self convertSizeToBacking:self.frame.size].height - p.y, u, ticks());
if(u && _lastInputRect.size.width && _lastInputRect.size.height)
[self resetLastInputRect];
+ */
}
- (void) sendmouse:(NSUInteger)u
{
+ /*
mousetrack(0, 0, u, ticks());
if(u && _lastInputRect.size.width && _lastInputRect.size.height)
[self resetLastInputRect];
+ */
}
- (void) mouseDown:(NSEvent*)event { [self mouseevent:event]; }
@@ -659,6 +675,7 @@
- (void)touchesEndedWithEvent:(NSEvent*)e
{
+ /*
if(_tapping
&& [e touchesMatchingPhase:NSTouchPhaseTouching inView:nil].count == 0
&& ticks() - _tapTime < 250){
@@ -675,6 +692,7 @@
}
_tapping = NO;
}
+ */
}
- (void)touchesCancelledWithEvent:(NSEvent*)e
@@ -689,19 +707,23 @@
- (void) resetCursorRects
{
+ /*
[super resetCursorRects];
lock(&cursor.lk);
[self addCursorRect:self.bounds cursor:currentCursor];
unlock(&cursor.lk);
+ */
}
- (void) reshape
{
+ /*
NSSize s = [self convertSizeToBacking:self.frame.size];
LOG(@"%g %g", s.width, s.height);
if(gscreen != nil){
screenresize(Rect(0, 0, s.width, s.height));
}
+ */
}
- (void)windowDidResize:(NSNotification *)notification
@@ -727,8 +749,10 @@
static void
keystroke(Rune r)
{
+ /*
kbdkey(r, 1);
kbdkey(r, 0);
+ */
}
// conforms to protocol NSTextInputClient
@@ -748,6 +772,7 @@
selectedRange:(NSRange)sRange
replacementRange:(NSRange)rRange
{
+ /*
NSString *str;
[self clearInput];
@@ -795,6 +820,7 @@
for(uint i = 0; i < l; ++i)
keystroke(Kleft);
}
+ */
}
- (void)unmarkText
{
@@ -824,6 +850,7 @@
- (void)insertText:(id)s
replacementRange:(NSRange)r
{
+ /*
NSUInteger i;
NSUInteger len;
@@ -835,6 +862,7 @@
[_tmpText deleteCharactersInRange:NSMakeRange(0, _tmpText.length)];
_markedRange = NSMakeRange(NSNotFound, 0);
_selectedRange = NSMakeRange(0, 0);
+ */
}
- (NSUInteger)characterIndexForPoint:(NSPoint)point
{
@@ -849,6 +877,7 @@
}
- (void)doCommandBySelector:(SEL)s
{
+ /*
NSEvent *e;
uint c, k;
@@ -857,6 +886,7 @@
k = evkey(c);
if(k>0)
keystroke(k);
+ */
}
// Helper for managing input rect approximately
@@ -876,6 +906,7 @@
- (void)clearInput
{
+ /*
if(_tmpText.length){
uint l = 1 + _tmpText.length - NSMaxRange(_selectedRange)
+ (_selectedRange.length > 0);
@@ -885,6 +916,7 @@
for(uint i = 0; i < l; ++i)
keystroke(Kbs);
}
+ */
}
@end
--- a/include/auth.h
+++ /dev/null
@@ -1,146 +1,0 @@
-#ifdef PLAN9
-#pragma src "/sys/src/libauth"
-#pragma lib "libauth.a"
-#endif
-
-/*
- * Interface for typical callers.
- */
-
-typedef struct AuthInfo AuthInfo;
-typedef struct Chalstate Chalstate;
-typedef struct Chapreply Chapreply;
-typedef struct MSchapreply MSchapreply;
-typedef struct UserPasswd UserPasswd;
-typedef struct AuthRpc AuthRpc;
-
-enum
-{
- MAXCHLEN= 256, /* max challenge length */
- MAXNAMELEN= 256, /* maximum name length */
- MD5LEN= 16,
-
- ARok = 0, /* rpc return values */
- ARdone,
- ARerror,
- ARneedkey,
- ARbadkey,
- ARwritenext,
- ARtoosmall,
- ARtoobig,
- ARrpcfailure,
- ARphase,
-
- AuthRpcMax = 4096,
-};
-
-struct AuthRpc
-{
- int afd;
- char ibuf[AuthRpcMax+1]; /* +1 for NUL in auth_rpc.c */
- char obuf[AuthRpcMax];
- char *arg;
- uint narg;
-};
-
-struct AuthInfo
-{
- char *cuid; /* caller id */
- char *suid; /* server id */
- char *cap; /* capability (only valid on server side) */
- int nsecret; /* length of secret */
- uchar *secret; /* secret */
-};
-
-struct Chalstate
-{
- char *user;
- char chal[MAXCHLEN];
- int nchal;
- void *resp;
- int nresp;
-
-/* for implementation only */
- int afd; /* to factotum */
- AuthRpc *rpc; /* to factotum */
- char userbuf[MAXNAMELEN]; /* temp space if needed */
- int userinchal; /* user was sent to obtain challenge */
-};
-
-struct Chapreply /* for protocol "chap" */
-{
- uchar id;
- char resp[MD5LEN];
-};
-
-struct MSchapreply /* for protocol "mschap" */
-{
- char LMresp[24]; /* Lan Manager response */
- char NTresp[24]; /* NT response */
-};
-
-struct UserPasswd
-{
- char *user;
- char *passwd;
-};
-
-extern int newns(char*, char*);
-extern int addns(char*, char*);
-
-extern int noworld(char*);
-extern int amount(int, char*, int, char*);
-
-extern int login(char*, char*, char*);
-
-typedef struct Attr Attr;
-enum {
- AttrNameval, /* name=val -- when matching, must have name=val */
- AttrQuery, /* name? -- when matching, must be present */
- AttrDefault, /* name=val -- when matching, if present must match INTERNAL */
-};
-struct Attr
-{
- int type;
- Attr *next;
- char *name;
- char *val;
-};
-
-typedef int AuthGetkey(char*);
-
-int _attrfmt(Fmt*);
-Attr *_copyattr(Attr*);
-Attr *_delattr(Attr*, char*);
-Attr *_findattr(Attr*, char*);
-void _freeattr(Attr*);
-Attr *_mkattr(int, char*, char*, Attr*);
-Attr *_parseattr(char*);
-char *_strfindattr(Attr*, char*);
-#ifdef VARARGCK
-#pragma varargck type "A" Attr*
-#endif
-
-extern AuthInfo* fauth_proxy(int, AuthRpc *rpc, AuthGetkey *getkey, char *params);
-extern AuthInfo* auth_proxy(int fd, AuthGetkey *getkey, char *fmt, ...);
-extern int auth_getkey(char*);
-extern int (*amount_getkey)(char*);
-extern void auth_freeAI(AuthInfo *ai);
-extern int auth_chuid(AuthInfo *ai, char *ns);
-extern Chalstate *auth_challenge(char*, ...);
-extern AuthInfo* auth_response(Chalstate*);
-extern int auth_respond(void*, uint, char*, uint, void*, uint, AuthGetkey *getkey, char*, ...);
-extern void auth_freechal(Chalstate*);
-extern AuthInfo* auth_userpasswd(char *user, char *passwd);
-extern UserPasswd* auth_getuserpasswd(AuthGetkey *getkey, char*, ...);
-extern AuthInfo* auth_getinfo(AuthRpc *rpc);
-extern AuthRpc* auth_allocrpc(int afd);
-extern Attr* auth_attr(AuthRpc *rpc);
-extern void auth_freerpc(AuthRpc *rpc);
-extern uint auth_rpc(AuthRpc *rpc, char *verb, void *a, int n);
-#ifdef VARARGCK
-#pragma varargck argpos auth_proxy 3
-#pragma varargck argpos auth_challenge 1
-#pragma varargck argpos auth_respond 8
-#pragma varargck argpos auth_getuserpasswd 2
-#endif
--- a/include/authsrv.h
+++ /dev/null
@@ -1,217 +1,0 @@
-/*
- * Interface for talking to authentication server.
- */
-typedef struct Ticket Ticket;
-typedef struct Ticketreq Ticketreq;
-typedef struct Authenticator Authenticator;
-typedef struct Nvrsafe Nvrsafe;
-typedef struct Passwordreq Passwordreq;
-typedef struct OChapreply OChapreply;
-typedef struct OMSchapreply OMSchapreply;
-
-typedef struct Authkey Authkey;
-
-enum
-{
- ANAMELEN= 28, /* name max size in previous proto */
- AERRLEN= 64, /* errstr max size in previous proto */
- DOMLEN= 48, /* authentication domain name length */
- DESKEYLEN= 7, /* encrypt/decrypt des key length */
- AESKEYLEN= 16, /* encrypt/decrypt aes key length */
-
- CHALLEN= 8, /* plan9 sk1 challenge length */
- NETCHLEN= 16, /* max network challenge length (used in AS protocol) */
- CONFIGLEN= 14,
- SECRETLEN= 32, /* secret max size */
- PASSWDLEN= 28, /* password max size */
-
- NONCELEN= 32,
-
- KEYDBOFF= 8, /* bytes of random data at key file's start */
- OKEYDBLEN= ANAMELEN+DESKEYLEN+4+2, /* old key file entry length */
- KEYDBLEN= OKEYDBLEN+SECRETLEN, /* key file entry length */
- OMD5LEN= 16,
-
- /* AuthPAK constants */
- PAKKEYLEN= 32,
- PAKSLEN= (448+7)/8, /* ed448 scalar */
- PAKPLEN= 4*PAKSLEN, /* point in extended format X,Y,Z,T */
- PAKHASHLEN= 2*PAKPLEN, /* hashed points PM,PN */
- PAKXLEN= PAKSLEN, /* random scalar secret key */
- PAKYLEN= PAKSLEN, /* decaf encoded public key */
-};
-
-/* encryption numberings (anti-replay) */
-enum
-{
- AuthTreq=1, /* ticket request */
- AuthChal=2, /* challenge box request */
- AuthPass=3, /* change password */
- AuthOK=4, /* fixed length reply follows */
- AuthErr=5, /* error follows */
- AuthMod=6, /* modify user */
- AuthApop=7, /* apop authentication for pop3 */
- AuthOKvar=9, /* variable length reply follows */
- AuthChap=10, /* chap authentication for ppp */
- AuthMSchap=11, /* MS chap authentication for ppp */
- AuthCram=12, /* CRAM verification for IMAP (RFC2195 & rfc2104) */
- AuthHttp=13, /* http domain login */
- AuthVNC=14, /* VNC server login (deprecated) */
- AuthPAK=19, /* authenticated diffie hellman key agreement */
- AuthTs=64, /* ticket encrypted with server's key */
- AuthTc, /* ticket encrypted with client's key */
- AuthAs, /* server generated authenticator */
- AuthAc, /* client generated authenticator */
- AuthTp, /* ticket encrypted with client's key for password change */
- AuthHr, /* http reply */
-};
-
-struct Ticketreq
-{
- char type;
- char authid[ANAMELEN]; /* server's encryption id */
- char authdom[DOMLEN]; /* server's authentication domain */
- char chal[CHALLEN]; /* challenge from server */
- char hostid[ANAMELEN]; /* host's encryption id */
- char uid[ANAMELEN]; /* uid of requesting user on host */
-};
-#define TICKREQLEN (3*ANAMELEN+CHALLEN+DOMLEN+1)
-
-struct Ticket
-{
- char num; /* replay protection */
- char chal[CHALLEN]; /* server challenge */
- char cuid[ANAMELEN]; /* uid on client */
- char suid[ANAMELEN]; /* uid on server */
- uchar key[NONCELEN]; /* nonce key */
-
- char form; /* (not transmitted) format (0 = des, 1 = ccpoly) */
-};
-#define MAXTICKETLEN (12+CHALLEN+2*ANAMELEN+NONCELEN+16)
-
-struct Authenticator
-{
- char num; /* replay protection */
- char chal[CHALLEN]; /* server/client challenge */
- uchar rand[NONCELEN]; /* server/client nonce */
-};
-#define MAXAUTHENTLEN (12+CHALLEN+NONCELEN+16)
-
-struct Passwordreq
-{
- char num;
- char old[PASSWDLEN];
- char new[PASSWDLEN];
- char changesecret;
- char secret[SECRETLEN]; /* new secret */
-};
-#define MAXPASSREQLEN (12+2*PASSWDLEN+1+SECRETLEN+16)
-
-struct OChapreply
-{
- uchar id;
- char uid[ANAMELEN];
- char resp[OMD5LEN];
-};
-#define OCHAPREPLYLEN (1+ANAMELEN+OMD5LEN)
-
-struct OMSchapreply
-{
- char uid[ANAMELEN];
- char LMresp[24]; /* Lan Manager response */
- char NTresp[24]; /* NT response */
-};
-#define OMSCHAPREPLYLEN (ANAMELEN+24+24)
-
-struct Authkey
-{
- char des[DESKEYLEN]; /* DES key from password */
- uchar aes[AESKEYLEN]; /* AES key from password */
- uchar pakkey[PAKKEYLEN]; /* shared key from AuthPAK exchange (see authpak_finish()) */
- uchar pakhash[PAKHASHLEN]; /* secret hash from AES key and user name (see authpak_hash()) */
-};
-
-/*
- * convert to/from wire format
- */
-extern int convT2M(Ticket*, char*, int, Authkey*);
-extern int convM2T(char*, int, Ticket*, Authkey*);
-extern int convA2M(Authenticator*, char*, int, Ticket*);
-extern int convM2A(char*, int, Authenticator*, Ticket*);
-extern int convTR2M(Ticketreq*, char*, int);
-extern int convM2TR(char*, int, Ticketreq*);
-extern int convPR2M(Passwordreq*, char*, int, Ticket*);
-extern int convM2PR(char*, int, Passwordreq*, Ticket*);
-
-/*
- * convert ascii password to auth key
- */
-extern void passtokey(Authkey*, char*);
-
-extern void passtodeskey(char key[DESKEYLEN], char *p);
-extern void passtoaeskey(uchar key[AESKEYLEN], char *p);
-
-/*
- * Nvram interface
- */
-enum {
- NVread = 0, /* just read */
- NVwrite = 1<<0, /* always prompt and rewrite nvram */
- NVwriteonerr = 1<<1, /* prompt and rewrite nvram when corrupt */
- NVwritemem = 1<<2, /* don't prompt, write nvram from argument */
-};
-
-/* storage layout */
-struct Nvrsafe
-{
- char machkey[DESKEYLEN]; /* file server's authid's des key */
- uchar machsum;
- char authkey[DESKEYLEN]; /* authid's des key from password */
- uchar authsum;
- /*
- * file server config string of device holding full configuration;
- * secstore key on non-file-servers.
- */
- char config[CONFIGLEN];
- uchar configsum;
- char authid[ANAMELEN]; /* auth userid, e.g., bootes */
- uchar authidsum;
- char authdom[DOMLEN]; /* auth domain, e.g., cs.bell-labs.com */
- uchar authdomsum;
-
- uchar aesmachkey[AESKEYLEN];
- uchar aesmachsum;
-};
-
-extern uchar nvcsum(void*, int);
-extern int readnvram(Nvrsafe*, int);
-extern char* readcons(char*, char*, int);
-
-/*
- * call up auth server
- */
-extern int authdial(char *netroot, char *authdom);
-
-/*
- * exchange messages with auth server
- */
-extern int _asgetpakkey(int, Ticketreq*, Authkey*);
-extern int _asgetticket(int, Ticketreq*, char*, int);
-extern int _asrequest(int, Ticketreq*);
-extern int _asgetresp(int, Ticket*, Authenticator*, Authkey *);
-extern int _asrdresp(int, char*, int);
-
-/*
- * AuthPAK protocol
- */
-typedef struct PAKpriv PAKpriv;
-struct PAKpriv
-{
- int isclient;
- uchar x[PAKXLEN];
- uchar y[PAKYLEN];
-};
-
-extern void authpak_hash(Authkey *k, char *u);
-extern void authpak_new(PAKpriv *p, Authkey *k, uchar y[PAKYLEN], int isclient);
-extern int authpak_finish(PAKpriv *p, Authkey *k, uchar y[PAKYLEN]);
--- a/include/ip.h
+++ /dev/null
@@ -1,38 +1,0 @@
-enum
-{
- IPaddrlen= 16,
- IPv4addrlen= 4,
- IPv4off= 12,
-};
-
-uchar* defmask(uchar*);
-void maskip(uchar*, uchar*, uchar*);
-int eipfmt(Fmt*);
-int isv4(uchar*);
-vlong parseip(uchar*, char*);
-vlong parseipmask(uchar*, char*, int);
-vlong parseipandmask(uchar*, uchar*, char*, char*);
-char* v4parseip(uchar*, char*);
-
-void hnputv(void*, uvlong);
-void hnputl(void*, uint);
-void hnputs(void*, ushort);
-uvlong nhgetv(void*);
-uint nhgetl(void*);
-ushort nhgets(void*);
-
-int v6tov4(uchar*, uchar*);
-void v4tov6(uchar*, uchar*);
-
-#define ipcmp(x, y) memcmp(x, y, IPaddrlen)
-#define ipmove(x, y) memmove(x, y, IPaddrlen)
-
-extern uchar IPv4bcast[IPaddrlen];
-extern uchar IPv4bcastobs[IPaddrlen];
-extern uchar IPv4allsys[IPaddrlen];
-extern uchar IPv4allrouter[IPaddrlen];
-extern uchar IPnoaddr[IPaddrlen];
-extern uchar v4prefix[IPaddrlen];
-extern uchar IPallbits[IPaddrlen];
-
-#define CLASS(p) ((*(uchar*)(p))>>6)
--- a/include/libsec.h
+++ /dev/null
@@ -1,589 +1,0 @@
-#ifndef _MPINT
-typedef struct mpint mpint;
-#endif
-
-/*
- * AES definitions
- */
-
-enum
-{
- AESbsize= 16,
- AESmaxkey= 32,
- AESmaxrounds= 14
-};
-
-typedef struct AESstate AESstate;
-struct AESstate
-{
- ulong setup;
- ulong offset;
- int rounds;
- int keybytes;
- void *ekey; /* expanded encryption round key */
- void *dkey; /* expanded decryption round key */
- uchar key[AESmaxkey]; /* unexpanded key */
- uchar ivec[AESbsize]; /* initialization vector */
- uchar storage[512]; /* storage for expanded keys */
-};
-
-/* block ciphers */
-extern void (*aes_encrypt)(ulong rk[], int Nr, uchar pt[16], uchar ct[16]);
-extern void (*aes_decrypt)(ulong rk[], int Nr, uchar ct[16], uchar pt[16]);
-
-void setupAESstate(AESstate *s, uchar key[], int nkey, uchar *ivec);
-
-void aesCBCencrypt(uchar *p, int len, AESstate *s);
-void aesCBCdecrypt(uchar *p, int len, AESstate *s);
-void aesCFBencrypt(uchar *p, int len, AESstate *s);
-void aesCFBdecrypt(uchar *p, int len, AESstate *s);
-void aesOFBencrypt(uchar *p, int len, AESstate *s);
-
-void aes_xts_encrypt(AESstate *tweak, AESstate *ecb, uvlong sectorNumber, uchar *input, uchar *output, ulong len);
-void aes_xts_decrypt(AESstate *tweak, AESstate *ecb, uvlong sectorNumber, uchar *input, uchar *output, ulong len);
-
-typedef struct AESGCMstate AESGCMstate;
-struct AESGCMstate
-{
- AESstate a;
-
- ulong H[4];
- ulong M[16][256][4];
-};
-
-void setupAESGCMstate(AESGCMstate *s, uchar *key, int keylen, uchar *iv, int ivlen);
-void aesgcm_setiv(AESGCMstate *s, uchar *iv, int ivlen);
-void aesgcm_encrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], AESGCMstate *s);
-int aesgcm_decrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], AESGCMstate *s);
-
-/*
- * Blowfish Definitions
- */
-
-enum
-{
- BFbsize = 8,
- BFrounds= 16
-};
-
-/* 16-round Blowfish */
-typedef struct BFstate BFstate;
-struct BFstate
-{
- ulong setup;
-
- uchar key[56];
- uchar ivec[8];
-
- u32int pbox[BFrounds+2];
- u32int sbox[1024];
-};
-
-void setupBFstate(BFstate *s, uchar key[], int keybytes, uchar *ivec);
-void bfCBCencrypt(uchar*, int, BFstate*);
-void bfCBCdecrypt(uchar*, int, BFstate*);
-void bfECBencrypt(uchar*, int, BFstate*);
-void bfECBdecrypt(uchar*, int, BFstate*);
-
-/*
- * Chacha definitions
- */
-
-enum
-{
- ChachaBsize= 64,
- ChachaKeylen= 256/8,
- ChachaIVlen= 96/8,
- XChachaIVlen= 192/8,
-};
-
-typedef struct Chachastate Chachastate;
-struct Chachastate
-{
- union{
- u32int input[16];
- struct {
- u32int constant[4];
- u32int key[8];
- u32int counter;
- u32int iv[3];
- };
- };
- u32int xkey[8];
- int rounds;
- int ivwords;
-};
-
-void setupChachastate(Chachastate*, uchar*, ulong, uchar*, ulong, int);
-void chacha_setiv(Chachastate *, uchar*);
-void chacha_setblock(Chachastate*, u64int);
-void chacha_encrypt(uchar*, ulong, Chachastate*);
-void chacha_encrypt2(uchar*, uchar*, ulong, Chachastate*);
-
-void hchacha(uchar h[32], uchar *key, ulong keylen, uchar nonce[16], int rounds);
-
-void ccpoly_encrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], Chachastate *cs);
-int ccpoly_decrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], Chachastate *cs);
-
-/*
- * Salsa definitions
- */
-enum
-{
- SalsaBsize= 64,
- SalsaKeylen= 256/8,
- SalsaIVlen= 64/8,
- XSalsaIVlen= 192/8,
-};
-
-typedef struct Salsastate Salsastate;
-struct Salsastate
-{
- u32int input[16];
- u32int xkey[8];
- int rounds;
- int ivwords;
-};
-
-void setupSalsastate(Salsastate*, uchar*, ulong, uchar*, ulong, int);
-void salsa_setiv(Salsastate*, uchar*);
-void salsa_setblock(Salsastate*, u64int);
-void salsa_encrypt(uchar*, ulong, Salsastate*);
-void salsa_encrypt2(uchar*, uchar*, ulong, Salsastate*);
-
-void salsa_core(u32int in[16], u32int out[16], int rounds);
-
-void hsalsa(uchar h[32], uchar *key, ulong keylen, uchar nonce[16], int rounds);
-
-/*
- * DES definitions
- */
-
-enum
-{
- DESbsize= 8
-};
-
-/* single des */
-typedef struct DESstate DESstate;
-struct DESstate
-{
- ulong setup;
- uchar key[8]; /* unexpanded key */
- ulong expanded[32]; /* expanded key */
- uchar ivec[8]; /* initialization vector */
-};
-
-void setupDESstate(DESstate *s, uchar key[8], uchar *ivec);
-void des_key_setup(uchar[8], ulong[32]);
-void block_cipher(ulong[32], uchar[8], int);
-void desCBCencrypt(uchar*, int, DESstate*);
-void desCBCdecrypt(uchar*, int, DESstate*);
-void desECBencrypt(uchar*, int, DESstate*);
-void desECBdecrypt(uchar*, int, DESstate*);
-
-/* for backward compatibility with 7-byte DES key format */
-void des56to64(uchar *k56, uchar *k64);
-void des64to56(uchar *k64, uchar *k56);
-void key_setup(uchar[7], ulong[32]);
-
-/* triple des encrypt/decrypt orderings */
-enum {
- DES3E= 0,
- DES3D= 1,
- DES3EEE= 0,
- DES3EDE= 2,
- DES3DED= 5,
- DES3DDD= 7
-};
-
-typedef struct DES3state DES3state;
-struct DES3state
-{
- ulong setup;
- uchar key[3][8]; /* unexpanded key */
- ulong expanded[3][32]; /* expanded key */
- uchar ivec[8]; /* initialization vector */
-};
-
-void setupDES3state(DES3state *s, uchar key[3][8], uchar *ivec);
-void triple_block_cipher(ulong[3][32], uchar[8], int);
-void des3CBCencrypt(uchar*, int, DES3state*);
-void des3CBCdecrypt(uchar*, int, DES3state*);
-void des3ECBencrypt(uchar*, int, DES3state*);
-void des3ECBdecrypt(uchar*, int, DES3state*);
-
-/*
- * digests
- */
-
-enum
-{
- SHA1dlen= 20, /* SHA digest length */
- SHA2_224dlen= 28, /* SHA-224 digest length */
- SHA2_256dlen= 32, /* SHA-256 digest length */
- SHA2_384dlen= 48, /* SHA-384 digest length */
- SHA2_512dlen= 64, /* SHA-512 digest length */
- MD4dlen= 16, /* MD4 digest length */
- MD5dlen= 16, /* MD5 digest length */
- RIPEMD160dlen= 20, /* RIPEMD-160 digest length */
- Poly1305dlen= 16, /* Poly1305 digest length */
-
- Hmacblksz = 64, /* in bytes; from rfc2104 */
-};
-
-typedef struct DigestState DigestState;
-struct DigestState
-{
- uvlong len;
- union {
- u32int state[16];
- u64int bstate[8];
- };
- uchar buf[256];
- int blen;
- char malloced;
- char seeded;
-};
-typedef struct DigestState SHAstate; /* obsolete name */
-typedef struct DigestState SHA1state;
-typedef struct DigestState SHA2_224state;
-typedef struct DigestState SHA2_256state;
-typedef struct DigestState SHA2_384state;
-typedef struct DigestState SHA2_512state;
-typedef struct DigestState MD5state;
-typedef struct DigestState MD4state;
-
-DigestState* md4(uchar*, ulong, uchar*, DigestState*);
-DigestState* md5(uchar*, ulong, uchar*, DigestState*);
-DigestState* ripemd160(uchar *, ulong, uchar *, DigestState *);
-DigestState* sha1(uchar*, ulong, uchar*, DigestState*);
-DigestState* sha2_224(uchar*, ulong, uchar*, DigestState*);
-DigestState* sha2_256(uchar*, ulong, uchar*, DigestState*);
-DigestState* sha2_384(uchar*, ulong, uchar*, DigestState*);
-DigestState* sha2_512(uchar*, ulong, uchar*, DigestState*);
-DigestState* hmac_x(uchar *p, ulong len, uchar *key, ulong klen,
- uchar *digest, DigestState *s,
- DigestState*(*x)(uchar*, ulong, uchar*, DigestState*),
- int xlen);
-DigestState* hmac_md5(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
-DigestState* hmac_sha1(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
-DigestState* hmac_sha2_224(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
-DigestState* hmac_sha2_256(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
-DigestState* hmac_sha2_384(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
-DigestState* hmac_sha2_512(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
-
-DigestState* poly1305(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
-
-/*
- * random number generation
- */
-void genrandom(uchar *buf, int nbytes);
-void prng(uchar *buf, int nbytes);
-ulong fastrand(void);
-ulong nfastrand(ulong);
-
-/*
- * primes
- */
-void genprime(mpint *p, int n, int accuracy); /* generate n-bit probable prime */
-void gensafeprime(mpint *p, mpint *alpha, int n, int accuracy); /* prime & generator */
-void genstrongprime(mpint *p, int n, int accuracy); /* generate n-bit strong prime */
-void DSAprimes(mpint *q, mpint *p, uchar seed[SHA1dlen]);
-int probably_prime(mpint *n, int nrep); /* miller-rabin test */
-int smallprimetest(mpint *p); /* returns -1 if not prime, 0 otherwise */
-
-/*
- * rc4
- */
-typedef struct RC4state RC4state;
-struct RC4state
-{
- uchar state[256];
- uchar x;
- uchar y;
-};
-
-void setupRC4state(RC4state*, uchar*, int);
-void rc4(RC4state*, uchar*, int);
-void rc4skip(RC4state*, int);
-void rc4back(RC4state*, int);
-
-/*
- * rsa
- */
-typedef struct RSApub RSApub;
-typedef struct RSApriv RSApriv;
-typedef struct PEMChain PEMChain;
-
-/* public/encryption key */
-struct RSApub
-{
- mpint *n; /* modulus */
- mpint *ek; /* exp (encryption key) */
-};
-
-/* private/decryption key */
-struct RSApriv
-{
- RSApub pub;
-
- mpint *dk; /* exp (decryption key) */
-
- /* precomputed values to help with chinese remainder theorem calc */
- mpint *p;
- mpint *q;
- mpint *kp; /* dk mod p-1 */
- mpint *kq; /* dk mod q-1 */
- mpint *c2; /* (inv p) mod q */
-};
-
-struct PEMChain{
- PEMChain*next;
- uchar *pem;
- int pemlen;
-};
-
-RSApriv* rsagen(int nlen, int elen, int rounds);
-RSApriv* rsafill(mpint *n, mpint *e, mpint *d, mpint *p, mpint *q);
-mpint* rsaencrypt(RSApub *k, mpint *in, mpint *out);
-mpint* rsadecrypt(RSApriv *k, mpint *in, mpint *out);
-RSApub* rsapuballoc(void);
-void rsapubfree(RSApub*);
-RSApriv* rsaprivalloc(void);
-void rsaprivfree(RSApriv*);
-RSApub* rsaprivtopub(RSApriv*);
-RSApub* X509toRSApub(uchar*, int, char*, int);
-RSApub* asn1toRSApub(uchar*, int);
-RSApriv* asn1toRSApriv(uchar*, int);
-void asn1dump(uchar *der, int len);
-uchar* decodePEM(char *s, char *type, int *len, char **new_s);
-PEMChain* decodepemchain(char *s, char *type);
-uchar* X509rsagen(RSApriv *priv, char *subj, ulong valid[2], int *certlen);
-uchar* X509rsareq(RSApriv *priv, char *subj, int *certlen);
-char* X509rsaverify(uchar *cert, int ncert, RSApub *pk);
-char* X509rsaverifydigest(uchar *sig, int siglen, uchar *edigest, int edigestlen, RSApub *pk);
-
-void X509dump(uchar *cert, int ncert);
-
-mpint* pkcs1padbuf(uchar *buf, int len, mpint *modulus, int blocktype);
-int pkcs1unpadbuf(uchar *buf, int len, mpint *modulus, int blocktype);
-int asn1encodeRSApub(RSApub *pk, uchar *buf, int len);
-int asn1encodedigest(DigestState* (*fun)(uchar*, ulong, uchar*, DigestState*),
- uchar *digest, uchar *buf, int len);
-
-
-/*
- * elgamal
- */
-typedef struct EGpub EGpub;
-typedef struct EGpriv EGpriv;
-typedef struct EGsig EGsig;
-
-/* public/encryption key */
-struct EGpub
-{
- mpint *p; /* modulus */
- mpint *alpha; /* generator */
- mpint *key; /* (encryption key) alpha**secret mod p */
-};
-
-/* private/decryption key */
-struct EGpriv
-{
- EGpub pub;
- mpint *secret; /* (decryption key) */
-};
-
-/* signature */
-struct EGsig
-{
- mpint *r, *s;
-};
-
-EGpriv* eggen(int nlen, int rounds);
-mpint* egencrypt(EGpub *k, mpint *in, mpint *out); /* deprecated */
-mpint* egdecrypt(EGpriv *k, mpint *in, mpint *out);
-EGsig* egsign(EGpriv *k, mpint *m);
-int egverify(EGpub *k, EGsig *sig, mpint *m);
-EGpub* egpuballoc(void);
-void egpubfree(EGpub*);
-EGpriv* egprivalloc(void);
-void egprivfree(EGpriv*);
-EGsig* egsigalloc(void);
-void egsigfree(EGsig*);
-EGpub* egprivtopub(EGpriv*);
-
-/*
- * dsa
- */
-typedef struct DSApub DSApub;
-typedef struct DSApriv DSApriv;
-typedef struct DSAsig DSAsig;
-
-/* public/encryption key */
-struct DSApub
-{
- mpint *p; /* modulus */
- mpint *q; /* group order, q divides p-1 */
- mpint *alpha; /* group generator */
- mpint *key; /* (encryption key) alpha**secret mod p */
-};
-
-/* private/decryption key */
-struct DSApriv
-{
- DSApub pub;
- mpint *secret; /* (decryption key) */
-};
-
-/* signature */
-struct DSAsig
-{
- mpint *r, *s;
-};
-
-DSApriv* dsagen(DSApub *opub); /* opub not checked for consistency! */
-DSAsig* dsasign(DSApriv *k, mpint *m);
-int dsaverify(DSApub *k, DSAsig *sig, mpint *m);
-DSApub* dsapuballoc(void);
-void dsapubfree(DSApub*);
-DSApriv* dsaprivalloc(void);
-void dsaprivfree(DSApriv*);
-DSAsig* dsasigalloc(void);
-void dsasigfree(DSAsig*);
-DSApub* dsaprivtopub(DSApriv*);
-
-/*
- * TLS
- */
-typedef struct Thumbprint{
- struct Thumbprint *next;
- uchar hash[SHA2_256dlen];
- uchar len;
-} Thumbprint;
-
-typedef struct TLSconn{
- char dir[40]; /* connection directory */
- uchar *cert; /* certificate (local on input, remote on output) */
- uchar *sessionID;
- uchar *psk;
- int certlen;
- int sessionIDlen;
- int psklen;
- int (*trace)(char*fmt, ...);
- PEMChain*chain; /* optional extra certificate evidence for servers to present */
- char *sessionType;
- uchar *sessionKey;
- int sessionKeylen;
- char *sessionConst;
- char *serverName;
- char *pskID;
-} TLSconn;
-
-/* tlshand.c */
-int tlsClient(int fd, TLSconn *c);
-int tlsServer(int fd, TLSconn *c);
-
-/* thumb.c */
-Thumbprint* initThumbprints(char *ok, char *crl, char *tag);
-void freeThumbprints(Thumbprint *ok);
-int okThumbprint(uchar *hash, int len, Thumbprint *ok);
-int okCertificate(uchar *cert, int len, Thumbprint *ok);
-
-/* readcert.c */
-uchar *readcert(char *filename, int *pcertlen);
-PEMChain*readcertchain(char *filename);
-
-typedef struct ECpoint{
- int inf;
- mpint *x;
- mpint *y;
- mpint *z; /* nil when using affine coordinates */
-} ECpoint;
-
-typedef ECpoint ECpub;
-typedef struct ECpriv{
- ECpoint a;
- mpint *d;
-} ECpriv;
-
-typedef struct ECdomain{
- mpint *p;
- mpint *a;
- mpint *b;
- ECpoint G;
- mpint *n;
- mpint *h;
-} ECdomain;
-
-void ecdominit(ECdomain *, void (*init)(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h));
-void ecdomfree(ECdomain *);
-
-void ecassign(ECdomain *, ECpoint *old, ECpoint *new);
-void ecadd(ECdomain *, ECpoint *a, ECpoint *b, ECpoint *s);
-void ecmul(ECdomain *, ECpoint *a, mpint *k, ECpoint *s);
-ECpoint* strtoec(ECdomain *, char *, char **, ECpoint *);
-ECpriv* ecgen(ECdomain *, ECpriv*);
-int ecverify(ECdomain *, ECpoint *);
-int ecpubverify(ECdomain *, ECpub *);
-void ecdsasign(ECdomain *, ECpriv *, uchar *, int, mpint *, mpint *);
-int ecdsaverify(ECdomain *, ECpub *, uchar *, int, mpint *, mpint *);
-void base58enc(uchar *, char *, int);
-int base58dec(char *, uchar *, int);
-
-ECpub* ecdecodepub(ECdomain *dom, uchar *, int);
-int ecencodepub(ECdomain *dom, ECpub *, uchar *, int);
-void ecpubfree(ECpub *);
-
-ECpub* X509toECpub(uchar *cert, int ncert, char *name, int nname, ECdomain *dom);
-char* X509ecdsaverify(uchar *cert, int ncert, ECdomain *dom, ECpub *pub);
-char* X509ecdsaverifydigest(uchar *sig, int siglen, uchar *edigest, int edigestlen, ECdomain *dom, ECpub *pub);
-
-/* curves */
-void secp256r1(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h);
-void secp256k1(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h);
-void secp384r1(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h);
-
-/*
- * Diffie-Hellman key exchange
- */
-
-typedef struct DHstate DHstate;
-struct DHstate
-{
- mpint *g; /* base g */
- mpint *p; /* large prime */
- mpint *q; /* subgroup prime */
- mpint *x; /* random secret */
- mpint *y; /* public key y = g**x % p */
-};
-
-/* generate new public key: y = g**x % p */
-mpint* dh_new(DHstate *dh, mpint *p, mpint *q, mpint *g);
-
-/* calculate shared key: k = y**x % p */
-mpint* dh_finish(DHstate *dh, mpint *y);
-
-/* Curve25519 elliptic curve, public key function */
-void curve25519(uchar mypublic[32], uchar secret[32], uchar basepoint[32]);
-
-/* Curve25519 diffie hellman */
-void curve25519_dh_new(uchar x[32], uchar y[32]);
-int curve25519_dh_finish(uchar x[32], uchar y[32], uchar z[32]);
-
-/* password-based key derivation function 2 (rfc2898) */
-void pbkdf2_x(uchar *p, ulong plen, uchar *s, ulong slen, ulong rounds, uchar *d, ulong dlen,
- DigestState* (*x)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*), int xlen);
-
-/* scrypt password-based key derivation function */
-char* scrypt(uchar *p, ulong plen, uchar *s, ulong slen,
- ulong N, ulong R, ulong P,
- uchar *d, ulong dlen);
-
-/* hmac-based key derivation function (rfc5869) */
-void hkdf_x(uchar *salt, ulong nsalt, uchar *info, ulong ninfo, uchar *key, ulong nkey, uchar *d, ulong dlen,
- DigestState* (*x)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*), int xlen);
-
-/* timing safe memcmp() */
-int tsmemcmp(void*, void*, ulong);
--- a/include/mp.h
+++ /dev/null
@@ -1,176 +1,0 @@
-#define _MPINT 1
-
-/*
- * the code assumes mpdigit to be at least an int
- * mpdigit must be an atomic type. mpdigit is defined
- * in the architecture specific u.h
- */
-typedef struct mpint mpint;
-
-struct mpint
-{
- int sign; /* +1 or -1 */
- int size; /* allocated digits */
- int top; /* significant digits */
- mpdigit *p;
- char flags;
-};
-
-enum
-{
- MPstatic= 0x01, /* static constant */
- MPnorm= 0x02, /* normalization status */
- MPtimesafe= 0x04, /* request time invariant computation */
- MPfield= 0x08, /* this mpint is a field modulus */
-
- Dbytes= sizeof(mpdigit), /* bytes per digit */
- Dbits= Dbytes*8 /* bits per digit */
-};
-
-/* allocation */
-void mpsetminbits(int n); /* newly created mpint's get at least n bits */
-mpint* mpnew(int n); /* create a new mpint with at least n bits */
-void mpfree(mpint *b);
-void mpbits(mpint *b, int n); /* ensure that b has at least n bits */
-mpint* mpnorm(mpint *b); /* dump leading zeros */
-mpint* mpcopy(mpint *b);
-void mpassign(mpint *old, mpint *new);
-
-/* random bits */
-mpint* mprand(int bits, void (*gen)(uchar*, int), mpint *b);
-/* return uniform random [0..n-1] */
-mpint* mpnrand(mpint *n, void (*gen)(uchar*, int), mpint *b);
-
-/* conversion */
-mpint* strtomp(char*, char**, int, mpint*); /* ascii */
-int mpfmt(Fmt*);
-char* mptoa(mpint*, int, char*, int);
-mpint* letomp(uchar*, uint, mpint*); /* byte array, little-endian */
-int mptole(mpint*, uchar*, uint, uchar**);
-void mptolel(mpint *b, uchar *p, int n);
-mpint* betomp(uchar*, uint, mpint*); /* byte array, big-endian */
-int mptobe(mpint*, uchar*, uint, uchar**);
-void mptober(mpint *b, uchar *p, int n);
-uint mptoui(mpint*); /* unsigned int */
-mpint* uitomp(uint, mpint*);
-int mptoi(mpint*); /* int */
-mpint* itomp(int, mpint*);
-uvlong mptouv(mpint*); /* unsigned vlong */
-mpint* uvtomp(uvlong, mpint*);
-vlong mptov(mpint*); /* vlong */
-mpint* vtomp(vlong, mpint*);
-
-/* divide 2 digits by one */
-void mpdigdiv(mpdigit *dividend, mpdigit divisor, mpdigit *quotient);
-
-/* in the following, the result mpint may be */
-/* the same as one of the inputs. */
-void mpadd(mpint *b1, mpint *b2, mpint *sum); /* sum = b1+b2 */
-void mpsub(mpint *b1, mpint *b2, mpint *diff); /* diff = b1-b2 */
-void mpleft(mpint *b, int shift, mpint *res); /* res = b<<shift */
-void mpright(mpint *b, int shift, mpint *res); /* res = b>>shift */
-void mpmul(mpint *b1, mpint *b2, mpint *prod); /* prod = b1*b2 */
-void mpexp(mpint *b, mpint *e, mpint *m, mpint *res); /* res = b**e mod m */
-void mpmod(mpint *b, mpint *m, mpint *remainder); /* remainder = b mod m */
-
-/* logical operations */
-void mpand(mpint *b1, mpint *b2, mpint *res);
-void mpbic(mpint *b1, mpint *b2, mpint *res);
-void mpor(mpint *b1, mpint *b2, mpint *res);
-void mpnot(mpint *b, mpint *res);
-void mpxor(mpint *b1, mpint *b2, mpint *res);
-void mptrunc(mpint *b, int n, mpint *res);
-void mpxtend(mpint *b, int n, mpint *res);
-void mpasr(mpint *b, int shift, mpint *res);
-
-/* modular arithmetic, time invariant when 0≤b1≤m-1 and 0≤b2≤m-1 */
-void mpmodadd(mpint *b1, mpint *b2, mpint *m, mpint *sum); /* sum = b1+b2 % m */
-void mpmodsub(mpint *b1, mpint *b2, mpint *m, mpint *diff); /* diff = b1-b2 % m */
-void mpmodmul(mpint *b1, mpint *b2, mpint *m, mpint *prod); /* prod = b1*b2 % m */
-
-/* quotient = dividend/divisor, remainder = dividend % divisor */
-void mpdiv(mpint *dividend, mpint *divisor, mpint *quotient, mpint *remainder);
-
-/* return neg, 0, pos as b1-b2 is neg, 0, pos */
-int mpcmp(mpint *b1, mpint *b2);
-
-/* res = s != 0 ? b1 : b2 */
-void mpsel(int s, mpint *b1, mpint *b2, mpint *res);
-
-/* extended gcd return d, x, and y, s.t. d = gcd(a,b) and ax+by = d */
-void mpextendedgcd(mpint *a, mpint *b, mpint *d, mpint *x, mpint *y);
-
-/* res = b**-1 mod m */
-void mpinvert(mpint *b, mpint *m, mpint *res);
-
-/* bit counting */
-int mpsignif(mpint*); /* number of sigificant bits in mantissa */
-int mplowbits0(mpint*); /* k, where n = 2**k * q for odd q */
-
-/* well known constants */
-extern mpint *mpzero, *mpone, *mptwo;
-
-/* sum[0:alen] = a[0:alen-1] + b[0:blen-1] */
-/* prereq: alen >= blen, sum has room for alen+1 digits */
-void mpvecadd(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *sum);
-
-/* diff[0:alen-1] = a[0:alen-1] - b[0:blen-1] */
-/* prereq: alen >= blen, diff has room for alen digits */
-void mpvecsub(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *diff);
-
-/* p[0:n] += m * b[0:n-1] */
-/* prereq: p has room for n+1 digits */
-void mpvecdigmuladd(mpdigit *b, int n, mpdigit m, mpdigit *p);
-
-/* p[0:n] -= m * b[0:n-1] */
-/* prereq: p has room for n+1 digits */
-int mpvecdigmulsub(mpdigit *b, int n, mpdigit m, mpdigit *p);
-
-/* p[0:alen+blen-1] = a[0:alen-1] * b[0:blen-1] */
-/* prereq: alen >= blen, p has room for m*n digits */
-void mpvecmul(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *p);
-void mpvectsmul(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *p);
-
-/* sign of a - b or zero if the same */
-int mpveccmp(mpdigit *a, int alen, mpdigit *b, int blen);
-int mpvectscmp(mpdigit *a, int alen, mpdigit *b, int blen);
-
-/* divide the 2 digit dividend by the one digit divisor and stick in quotient */
-/* we assume that the result is one digit - overflow is all 1's */
-void mpdigdiv(mpdigit *dividend, mpdigit divisor, mpdigit *quotient);
-
-/* playing with magnitudes */
-int mpmagcmp(mpint *b1, mpint *b2);
-void mpmagadd(mpint *b1, mpint *b2, mpint *sum); /* sum = b1+b2 */
-void mpmagsub(mpint *b1, mpint *b2, mpint *sum); /* sum = b1+b2 */
-
-/* chinese remainder theorem */
-typedef struct CRTpre CRTpre; /* precomputed values for converting */
- /* twixt residues and mpint */
-typedef struct CRTres CRTres; /* residue form of an mpint */
-
-struct CRTres
-{
- int n; /* number of residues */
- mpint *r[1]; /* residues */
-};
-
-CRTpre* crtpre(int, mpint**); /* precompute conversion values */
-CRTres* crtin(CRTpre*, mpint*); /* convert mpint to residues */
-void crtout(CRTpre*, CRTres*, mpint*); /* convert residues to mpint */
-void crtprefree(CRTpre*);
-void crtresfree(CRTres*);
-
-/* fast field arithmetic */
-typedef struct Mfield Mfield;
-
-struct Mfield
-{
- mpint m;
- int (*reduce)(Mfield*, mpint*, mpint*);
-};
-
-mpint *mpfield(mpint*);
-
-Mfield *gmfield(mpint*);
-Mfield *cnfield(mpint*);
--- a/kern/Makefile
+++ b/kern/Makefile
@@ -9,23 +9,14 @@
chan.$O\
data.$O\
dev.$O\
- devaudio.$O\
- devaudio-$(AUDIO).$O\
devcmd.$O\
devcons.$O\
- devdraw.$O\
devenv.$O\
devfs-$(OS).$O\
- devip.$O\
- devip-$(OS).$O\
- devkbd.$O\
devlfd-$(OS).$O\
devmnt.$O\
- devmouse.$O\
devpipe.$O\
devroot.$O\
- devssl.$O\
- devtls.$O\
devtab.$O\
dirread.$O\
error.$O\
@@ -43,7 +34,6 @@
time.$O\
qio.$O\
qlock.$O\
- term.$O\
wait.$O\
waserror.$O\
$(OS).$O
--- a/kern/devaudio-alsa.c
+++ /dev/null
@@ -1,108 +1,0 @@
-/*
- * ALSA
- */
-#include <alsa/asoundlib.h>
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-#include "devaudio.h"
-
-enum
-{
- Channels = 2,
- Rate = 44100,
- Bits = 16,
-};
-
-static snd_pcm_t *playback;
-static snd_pcm_t *capture;
-static int speed = Rate;
-
-/* maybe this should return -1 instead of sysfatal */
-void
-audiodevopen(void)
-{
- if(snd_pcm_open(&playback, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0)
- error("snd_pcm_open playback");
-
- if(snd_pcm_set_params(playback, SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_INTERLEAVED, 2, speed, 1, 500000) < 0)
- error("snd_pcm_set_params playback");
-
- if(snd_pcm_prepare(playback) < 0)
- error("snd_pcm_prepare playback");
-
- if(snd_pcm_open(&capture, "default", SND_PCM_STREAM_CAPTURE, 0) < 0)
- error("snd_pcm_open capture");
-
- if(snd_pcm_set_params(capture, SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_INTERLEAVED, 2, speed, 1, 500000) < 0)
- error("snd_pcm_set_params capture");
-
- if(snd_pcm_prepare(capture) < 0)
- error("snd_pcm_prepare capture");
-}
-
-void
-audiodevclose(void)
-{
- snd_pcm_drain(playback);
- snd_pcm_close(playback);
-
- snd_pcm_close(capture);
-}
-
-void
-audiodevsetvol(int what, int left, int right)
-{
- if(what == Vspeed){
- speed = left;
- return;
- }
-}
-
-void
-audiodevgetvol(int what, int *left, int *right)
-{
- if(what == Vspeed){
- *left = *right = speed;
- return;
- }
-
- *left = *right = 100;
-}
-
-int
-audiodevwrite(void *v, int n)
-{
- snd_pcm_sframes_t frames;
- int tot, m;
-
- for(tot = 0; tot < n; tot += m){
- do {
- frames = snd_pcm_writei(playback, v+tot, (n-tot)/4);
- } while(frames == -EAGAIN);
- if (frames < 0)
- frames = snd_pcm_recover(playback, frames, 0);
- if (frames < 0)
- error((char*)snd_strerror(frames));
- m = frames*4;
- }
-
- return tot;
-}
-
-int
-audiodevread(void *v, int n)
-{
- snd_pcm_sframes_t frames;
-
- do {
- frames = snd_pcm_readi(capture, v, n/4);
- } while(frames == -EAGAIN);
-
- if (frames < 0)
- error((char*)snd_strerror(frames));
-
- return frames*4;
-}
--- a/kern/devaudio-none.c
+++ /dev/null
@@ -1,49 +1,0 @@
-/*
- * Linux and BSD
- */
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-#include "devaudio.h"
-
-/* maybe this should return -1 instead of sysfatal */
-void
-audiodevopen(void)
-{
- error("no audio support");
-}
-
-void
-audiodevclose(void)
-{
- error("no audio support");
-}
-
-int
-audiodevread(void *a, int n)
-{
- error("no audio support");
- return -1;
-}
-
-int
-audiodevwrite(void *a, int n)
-{
- error("no audio support");
- return -1;
-}
-
-void
-audiodevsetvol(int what, int left, int right)
-{
- error("no audio support");
-}
-
-void
-audiodevgetvol(int what, int *left, int *right)
-{
- error("no audio support");
-}
-
--- a/kern/devaudio-pipewire.c
+++ /dev/null
@@ -1,189 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-#include "devaudio.h"
-
-#undef long
-#undef ulong
-#include <pipewire/pipewire.h>
-#include <spa/param/audio/format-utils.h>
-
-static struct {
- Lock lk;
- Rendez w;
- int init;
- struct pw_main_loop *loop;
- struct pw_stream *output;
-
- char buf[2*2*44100/10]; /* 1/10th sec */
- int written; /* 0 means empty buffer */
-} pwstate;
-
-static char *argv[] = { "drawcpu" };
-static int argc = 1;
-
-static void
-on_process(void *data)
-{
- struct pw_buffer *b;
- struct spa_buffer *buf;
- int16_t *dst;
- int n;
-
- lock(&pwstate.lk);
- if(pwstate.written == sizeof(pwstate.buf))
- wakeup(&pwstate.w);
- if(pwstate.written == 0){
- unlock(&pwstate.lk);
- return;
- }
-
- if((b = pw_stream_dequeue_buffer(pwstate.output)) == nil)
- return;
- buf = b->buffer;
- dst = buf->datas[0].data;
-
- n = pwstate.written;
- if(n > buf->datas[0].maxsize)
- n = buf->datas[0].maxsize;
- memcpy(dst, pwstate.buf, n);
- buf->datas[0].chunk->offset = 0;
- buf->datas[0].chunk->stride = sizeof(int16_t) * 2;
- buf->datas[0].chunk->size = n;
- pwstate.written -= n;
- if(pwstate.written > 0)
- memmove(pwstate.buf, pwstate.buf+n, pwstate.written);
-
- pw_stream_queue_buffer(pwstate.output, b);
- unlock(&pwstate.lk);
-}
-
-static const struct pw_stream_events stream_events = {
- PW_VERSION_STREAM_EVENTS,
- .process = on_process,
-};
-
-static void
-pwproc(void *arg)
-{
- struct pw_main_loop *loop;
-
- loop = arg;
- pw_main_loop_run(loop);
- pexit("", 0);
-}
-
-void
-audiodevopen(void)
-{
- const struct spa_pod *params[1];
- struct spa_pod_builder b = SPA_POD_BUILDER_INIT(pwstate.buf, sizeof(pwstate.buf));
- int err;
-
- lock(&pwstate.lk);
- pwstate.written = 0;
- if(pwstate.init == 0){
- pw_init(&argc, (char***)&argv);
- pwstate.init++;
- pwstate.loop = pw_main_loop_new(NULL);
- if(pwstate.loop == NULL)
- sysfatal("could not create loop");
- }
-
- pwstate.output = pw_stream_new_simple(
- pw_main_loop_get_loop(pwstate.loop),
- "drawcpu",
- pw_properties_new(
- PW_KEY_NODE_NAME, "drawcpu",
- PW_KEY_MEDIA_TYPE, "Audio",
- PW_KEY_MEDIA_CATEGORY, "Playback",
- PW_KEY_MEDIA_ROLE, "Music",
- NULL),
- &stream_events,
- NULL);
-
- if(pwstate.output == NULL){
- unlock(&pwstate.lk);
- error("could not create pipewire output");
- return;
- }
- params[0] = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat,
- &SPA_AUDIO_INFO_RAW_INIT(
- .format = SPA_AUDIO_FORMAT_S16_LE,
- .channels = 2,
- .rate = 44100 ));
-
- err = pw_stream_connect(pwstate.output,
- PW_DIRECTION_OUTPUT,
- PW_ID_ANY,
- PW_STREAM_FLAG_AUTOCONNECT |
- PW_STREAM_FLAG_MAP_BUFFERS |
- PW_STREAM_FLAG_RT_PROCESS,
- params, 1);
-
- unlock(&pwstate.lk);
- if(err < 0){
- error("could not connect pipewire stream");
- return;
- }
-
- kproc("pipewire main loop", pwproc, pwstate.loop);
-}
-
-void
-audiodevclose(void)
-{
- pw_main_loop_quit(pwstate.loop);
- pw_stream_destroy(pwstate.output);
-}
-
-int
-audiodevread(void *a, int n)
-{
- error("no record support");
- return -1;
-}
-
-static int
-canwrite(void *arg)
-{
- return pwstate.written < sizeof(pwstate.buf);
-}
-
-int
-audiodevwrite(void *a, int n)
-{
- int w, x, max;
- char *p;
-
- w = n;
- for(p = a; n > 0; p += x, n -= x){
- lock(&pwstate.lk);
- max = sizeof(pwstate.buf) - pwstate.written;
- x = n > max ? max : n;
- if(x < 1){
- unlock(&pwstate.lk);
- sleep(&pwstate.w, canwrite, 0);
- }else{
- memmove(pwstate.buf+pwstate.written, p, x);
- pwstate.written += x;
- unlock(&pwstate.lk);
- }
- }
- return w;
-}
-
-void
-audiodevsetvol(int what, int left, int right)
-{
- error("no volume support");
-}
-
-void
-audiodevgetvol(int what, int *left, int *right)
-{
- error("no volume support");
-}
-
--- a/kern/devaudio-sndio.c
+++ /dev/null
@@ -1,78 +1,0 @@
-#include <sndio.h>
-
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-#include "devaudio.h"
-
-enum
-{
- Channels = 2,
- Rate = 44100,
- Bits = 16,
-};
-
-static struct sio_hdl *hdl;
-static struct sio_par par;
-
-void
-audiodevopen(void)
-{
- hdl = sio_open(SIO_DEVANY, SIO_PLAY, 0);
- if(hdl == NULL){
- error("sio_open failed");
- return;
- }
-
- sio_initpar(&par);
-
- par.bits = Bits;
- par.pchan = Channels;
- par.rate = Rate;
- par.appbufsz = 288000;
-
- if(!sio_setpar(hdl, &par) || !sio_start(hdl)){
- sio_close(hdl);
- error("sio_setpar/sio_start failed");
- return;
- }
-}
-
-void
-audiodevclose(void)
-{
- sio_close(hdl);
-}
-
-void
-audiodevsetvol(int what, int left, int right)
-{
- USED(what);
- USED(left);
- USED(right);
- error("not supported");
-}
-
-void
-audiodevgetvol(int what, int *left, int *right)
-{
- USED(what);
- USED(left);
- USED(right);
- error("not supported");
-}
-
-int
-audiodevwrite(void *v, int n)
-{
- return sio_write(hdl, v, n);
-}
-
-int
-audiodevread(void *v, int n)
-{
- error("no reading");
- return -1;
-}
--- a/kern/devaudio-sun.c
+++ /dev/null
@@ -1,268 +1,0 @@
-/*
- * Sun
- */
-#include <sys/ioctl.h>
-#include <sys/audio.h>
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-#include "devaudio.h"
-
-enum
-{
- Channels = 2,
- Rate = 44100,
- Bits = 16,
-};
-
-static char* afn = 0;
-static char* cfn = 0;
-static int afd = -1;
-static int cfd = -1;
-static int speed = Rate;
-static int needswap = -1;
-
-static void
-audiodevinit(void)
-{
- uchar *p;
- ushort leorder;
-
- if ((afn = getenv("AUDIODEV")) == nil)
- afn = "/dev/audio";
- cfn = (char*)malloc(strlen(afn) + 3 + 1);
- if(cfn == nil)
- panic("out of memory");
- strcpy(cfn, afn);
- strcat(cfn, "ctl");
-
- /*
- * Plan 9 /dev/audio is always little endian;
- * solaris /dev/audio seems to expect native byte order,
- * so on big endian machine (like sparc) we have to swap.
- */
- leorder = (ushort) 0x0100;
- p = (uchar*)&leorder;
- if (p[0] == 0 && p[1] == 1) {
- /* little-endian: nothing to do */
- needswap = 0;
- } else {
- /* big-endian: translate Plan 9 little-endian */
- needswap = 1;
- }
-}
-
-/* maybe this should return -1 instead of sysfatal */
-void
-audiodevopen(void)
-{
- audio_info_t info;
- struct audio_device ad;
-
- if (afn == nil || cfn == nil)
- audiodevinit();
- if((afd = open(afn, O_WRONLY)) < 0)
- goto err;
- if(cfd < 0 && (cfd = open(cfn, O_RDWR)) < 0)
- goto err;
-
- AUDIO_INITINFO(&info);
- info.play.precision = Bits;
- info.play.channels = Channels;
- info.play.sample_rate = speed;
- info.play.encoding = AUDIO_ENCODING_LINEAR;
- if(ioctl(afd, AUDIO_SETINFO, &info) < 0)
- goto err;
-
- return;
-
-err:
- if(afd >= 0)
- close(afd);
- afd = -1;
- if(cfd >= 0)
- close(cfd);
- cfd = -1;
- oserror();
-}
-
-void
-audiodevclose(void)
-{
- if(afd >= 0)
- close(afd);
- if(cfd >= 0)
- close(cfd);
- afd = -1;
- cfd = -1;
-}
-
-static double
-fromsun(double val, double min, double max)
-{
- return (val-min) / (max-min);
-}
-
-static double
-tosun(double val, double min, double max)
-{
- return val*(max-min) + min;
-}
-
-static void
-setvolbal(double left, double right)
-{
- audio_info_t info;
- double vol, bal;
-
- if (left < 0 || right < 0) {
- /* should not happen */
- return;
- } else if (left == right) {
- vol = tosun(left/100.0, AUDIO_MIN_GAIN, AUDIO_MAX_GAIN);
- bal = AUDIO_MID_BALANCE;
- } else if (left < right) {
- vol = tosun(right/100.0, AUDIO_MIN_GAIN, AUDIO_MAX_GAIN);
- bal = tosun(1.0 - left/right, AUDIO_MID_BALANCE, AUDIO_RIGHT_BALANCE);
- } else if (right < left) {
- vol = tosun(left/100.0, AUDIO_MIN_GAIN, AUDIO_MAX_GAIN);
- bal = tosun(1.0 - right/left, AUDIO_MID_BALANCE, AUDIO_LEFT_BALANCE);
- }
- AUDIO_INITINFO(&info);
- info.play.gain = (long)(vol+0.5);
- info.play.balance = (long)(bal+0.5);
- if(ioctl(cfd, AUDIO_SETINFO, &info) < 0)
- oserror();
-}
-
-static void
-getvolbal(int *left, int *right)
-{
- audio_info_t info;
- double gain, bal, vol, l, r;
-
- AUDIO_INITINFO(&info);
- if (ioctl(cfd, AUDIO_GETINFO, &info) < 0)
- oserror();
-
- gain = info.play.gain;
- bal = info.play.balance;
- vol = fromsun(gain, AUDIO_MIN_GAIN, AUDIO_MAX_GAIN) * 100.0;
-
- if (bal == AUDIO_MID_BALANCE) {
- l = r = vol;
- } else if (bal < AUDIO_MID_BALANCE) {
- l = vol;
- r = vol * (1.0 - fromsun(bal, AUDIO_MID_BALANCE, AUDIO_LEFT_BALANCE));
- } else {
- r = vol;
- l = vol * (1.0 - fromsun(bal, AUDIO_MID_BALANCE, AUDIO_RIGHT_BALANCE));
- }
- *left = (long)(l+0.5);
- *right = (long)(r+0.5);
- return;
-}
-
-void
-audiodevsetvol(int what, int left, int right)
-{
- audio_info_t info;
- ulong x;
- int l, r;
-
- if (afn == nil || cfn == nil)
- audiodevinit();
- if(cfd < 0 && (cfd = open(cfn, O_RDWR)) < 0) {
- cfd = -1;
- oserror();
- }
-
- if(what == Vspeed){
- x = left;
- AUDIO_INITINFO(&info);
- info.play.sample_rate = x;
- if(ioctl(cfd, AUDIO_SETINFO, &info) < 0)
- oserror();
- speed = x;
- return;
- }
- if(what == Vaudio){
- getvolbal(&l, &r);
- if (left < 0)
- setvolbal(l, right);
- else if (right < 0)
- setvolbal(left, r);
- else
- setvolbal(left, right);
- return;
- }
-}
-
-void
-audiodevgetvol(int what, int *left, int *right)
-{
- audio_info_t info;
-
- if (afn == nil || cfn == nil)
- audiodevinit();
- if(cfd < 0 && (cfd = open(cfn, O_RDWR)) < 0) {
- cfd = -1;
- oserror();
- }
- switch(what) {
- case Vspeed:
- *left = *right = speed;
- break;
- case Vaudio:
- getvolbal(left, right);
- break;
- case Vtreb:
- case Vbass:
- *left = *right = 50;
- break;
- default:
- *left = *right = 0;
- }
-}
-
-
-static uchar *buf = 0;
-static int nbuf = 0;
-
-int
-audiodevwrite(void *v, int n)
-{
- int i, m, tot;
- uchar *p;
-
- if (needswap) {
- if (nbuf < n) {
- buf = (uchar*)erealloc(buf, n);
- if(buf == nil)
- panic("out of memory");
- nbuf = n;
- }
-
- p = (uchar*)v;
- for(i=0; i+1<n; i+=2) {
- buf[i] = p[i+1];
- buf[i+1] = p[i];
- }
- p = buf;
- } else
- p = (uchar*)v;
-
- for(tot=0; tot<n; tot+=m)
- if((m = write(afd, p+tot, n-tot)) <= 0)
- oserror();
- return tot;
-}
-
-int
-audiodevread(void *v, int n)
-{
- error("no reading");
- return -1;
-}
--- a/kern/devaudio-unix.c
+++ /dev/null
@@ -1,183 +1,0 @@
-/*
- * Linux and BSD
- */
-#include <sys/ioctl.h>
-#ifdef __linux__
-#include <linux/soundcard.h>
-#else
-#include <sys/soundcard.h>
-#endif
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-#include "devaudio.h"
-
-enum
-{
- Channels = 2,
- Rate = 44100,
- Bits = 16,
- Bigendian = 1,
-};
-
-static int afd = -1;
-static int cfd= -1;
-static int speed;
-
-/* maybe this should return -1 instead of sysfatal */
-void
-audiodevopen(void)
-{
- int t;
- ulong ul;
-
- afd = -1;
- cfd = -1;
- if((afd = open("/dev/dsp", OWRITE)) < 0)
- goto err;
- if((cfd = open("/dev/mixer", ORDWR)) < 0)
- goto err;
-
- t = Bits;
- if(ioctl(afd, SNDCTL_DSP_SAMPLESIZE, &t) < 0)
- goto err;
-
- t = Channels-1;
- if(ioctl(afd, SNDCTL_DSP_STEREO, &t) < 0)
- goto err;
-
- speed = Rate;
- ul = Rate;
- if(ioctl(afd, SNDCTL_DSP_SPEED, &ul) < 0)
- goto err;
-
- return;
-
-err:
- if(afd >= 0)
- close(afd);
- afd = -1;
- oserror();
-}
-
-void
-audiodevclose(void)
-{
- close(afd);
- close(cfd);
- afd = -1;
- cfd = -1;
-}
-
-static struct {
- int id9;
- int id;
-} names[] = {
- Vaudio, SOUND_MIXER_VOLUME,
- Vbass, SOUND_MIXER_BASS,
- Vtreb, SOUND_MIXER_TREBLE,
- Vline, SOUND_MIXER_LINE,
- Vpcm, SOUND_MIXER_PCM,
- Vsynth, SOUND_MIXER_SYNTH,
- Vcd, SOUND_MIXER_CD,
- Vmic, SOUND_MIXER_MIC,
-// "record", SOUND_MIXER_RECLEV,
-// "mix", SOUND_MIXER_IMIX,
-// "pcm2", SOUND_MIXER_ALTPCM,
- Vspeaker, SOUND_MIXER_SPEAKER
-// "line1", SOUND_MIXER_LINE1,
-// "line2", SOUND_MIXER_LINE2,
-// "line3", SOUND_MIXER_LINE3,
-// "digital1", SOUND_MIXER_DIGITAL1,
-// "digital2", SOUND_MIXER_DIGITAL2,
-// "digital3", SOUND_MIXER_DIGITAL3,
-// "phonein", SOUND_MIXER_PHONEIN,
-// "phoneout", SOUND_MIXER_PHONEOUT,
-// "radio", SOUND_MIXER_RADIO,
-// "video", SOUND_MIXER_VIDEO,
-// "monitor", SOUND_MIXER_MONITOR,
-// "igain", SOUND_MIXER_IGAIN,
-// "ogain", SOUND_MIXER_OGAIN,
-};
-
-static int
-lookname(int id9)
-{
- int i;
-
- for(i=0; i<nelem(names); i++)
- if(names[i].id9 == id9)
- return names[i].id;
- return -1;
-}
-
-void
-audiodevsetvol(int what, int left, int right)
-{
- int id;
- ulong x;
- int can, v;
-
- if(cfd < 0)
- error("audio device not open");
- if(what == Vspeed){
- x = left;
- if(ioctl(afd, SNDCTL_DSP_SPEED, &x) < 0)
- oserror();
- speed = x;
- return;
- }
- if((id = lookname(what)) < 0)
- return;
- if(ioctl(cfd, SOUND_MIXER_READ_DEVMASK, &can) < 0)
- can = ~0;
- if(!(can & (1<<id)))
- return;
- v = left | (right<<8);
- if(ioctl(cfd, MIXER_WRITE(id), &v) < 0)
- oserror();
-}
-
-void
-audiodevgetvol(int what, int *left, int *right)
-{
- int id;
- int can, v;
-
- if(cfd < 0)
- error("audio device not open");
- if(what == Vspeed){
- *left = *right = speed;
- return;
- }
- if((id = lookname(what)) < 0)
- return;
- if(ioctl(cfd, SOUND_MIXER_READ_DEVMASK, &can) < 0)
- can = ~0;
- if(!(can & (1<<id)))
- return;
- if(ioctl(cfd, MIXER_READ(id), &v) < 0)
- oserror();
- *left = v&0xFF;
- *right = (v>>8)&0xFF;
-}
-
-int
-audiodevwrite(void *v, int n)
-{
- int m, tot;
-
- for(tot=0; tot<n; tot+=m)
- if((m = write(afd, (uchar*)v+tot, n-tot)) <= 0)
- oserror();
- return tot;
-}
-
-int
-audiodevread(void *v, int n)
-{
- error("no reading");
- return -1;
-}
--- a/kern/devaudio-win32.c
+++ /dev/null
@@ -1,111 +1,0 @@
-#include <windows.h>
-#include <mmsystem.h>
-
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-#include "devaudio.h"
-
-enum
-{
- Channels = 2,
- Rate = 44100,
- Bits = 16,
-};
-
-typedef struct Waveblock Waveblock;
-struct Waveblock {
- WAVEHDR h;
- uchar s[2048];
-};
-
-static HWAVEOUT waveout;
-static Waveblock blk[16];
-static uint blkidx;
-
-void
-audiodevopen(void)
-{
- WAVEFORMATEX f;
-
- memset(&f, 0, sizeof(f));
- f.nSamplesPerSec = Rate;
- f.wBitsPerSample = Bits;
- f.nChannels = Channels;
- f.cbSize = 0;
- f.wFormatTag = WAVE_FORMAT_PCM;
- f.nBlockAlign = (f.wBitsPerSample/8) * f.nChannels;
- f.nAvgBytesPerSec = f.nBlockAlign * f.nSamplesPerSec;
- if(waveOutOpen(&waveout, WAVE_MAPPER, &f, 0, 0, CALLBACK_NULL) != MMSYSERR_NOERROR)
- oserror();
-}
-
-void
-audiodevclose(void)
-{
- waveOutClose(waveout);
- waveout = 0;
-}
-
-void
-audiodevsetvol(int what, int left, int right)
-{
- DWORD v;
-
- //Windows uses a 0-0xFFFF scale, plan9 uses 0-100
- v = right*0xFFFF/100;
- v = (v<<16)|(left*0xFFFF/100);
- if(waveOutSetVolume(waveout, v) != MMSYSERR_NOERROR)
- oserror();
-}
-
-void
-audiodevgetvol(int what, int *left, int *right)
-{
- DWORD v;
-
- if(waveOutGetVolume(waveout, &v) != MMSYSERR_NOERROR)
- oserror();
- *left = (v&0xFFFF)*100/0xFFFF;
- *right = ((v>>16)&0xFFFF)*100/0xFFFF;
-}
-
-int
-audiodevwrite(void *v, int n)
-{
- Waveblock *b;
- int m;
-
- m = 0;
- while(n > sizeof(b->s)){
- audiodevwrite(v, sizeof(b->s));
- v = (uchar*)v + sizeof(b->s);
- n -= sizeof(b->s);
- m += sizeof(b->s);
- }
-
- b = &blk[blkidx++ % nelem(blk)];
- if(b->h.dwFlags & WHDR_PREPARED){
- while(waveOutUnprepareHeader(waveout, &b->h, sizeof(b->h)) == WAVERR_STILLPLAYING)
- osmsleep(50);
- }
- memmove(b->s, v, n);
- b->h.lpData = (void*)b->s;
- b->h.dwBufferLength = n;
- waveOutPrepareHeader(waveout, &b->h, sizeof(b->h));
- waveOutWrite(waveout, &b->h, sizeof(b->h));
-
- return m + n;
-}
-
-int
-audiodevread(void *v, int n)
-{
- USED(v);
- USED(n);
-
- error("no reading");
- return -1;
-}
--- a/kern/devaudio.c
+++ /dev/null
@@ -1,377 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-#include "devaudio.h"
-
-enum
-{
- Qdir = 0,
- Qaudio,
- Qvolume,
-
- Aclosed = 0,
- Aread,
- Awrite,
-
- Speed = 44100,
- Ncmd = 50, /* max volume command words */
-};
-
-Dirtab
-audiodir[] =
-{
- ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
- "audio", {Qaudio}, 0, 0666,
- "volume", {Qvolume}, 0, 0666,
-};
-
-static struct
-{
- QLock lk;
- Rendez vous;
- int amode; /* Aclosed/Aread/Awrite for /audio */
-} audio;
-
-#define aqlock(a) qlock(&(a)->lk)
-#define aqunlock(a) qunlock(&(a)->lk)
-
-static struct
-{
- char* name;
- int flag;
- int ilval; /* initial values */
- int irval;
-} volumes[] =
-{
- "audio", Fout, 50, 50,
- "synth", Fin|Fout, 0, 0,
- "cd", Fin|Fout, 0, 0,
- "line", Fin|Fout, 0, 0,
- "mic", Fin|Fout|Fmono, 0, 0,
- "speaker", Fout|Fmono, 0, 0,
-
- "treb", Fout, 50, 50,
- "bass", Fout, 50, 50,
-
- "speed", Fin|Fout|Fmono, Speed, Speed,
-
- "pcm", Fout, 50, 50,
- 0
-};
-
-static char Emode[] = "illegal open mode";
-static char Evolume[] = "illegal volume specifier";
-
-static void
-resetlevel(void)
-{
- int i;
-
- for(i=0; volumes[i].name; i++)
- audiodevsetvol(i, volumes[i].ilval, volumes[i].irval);
-}
-
-static void
-audioinit(void)
-{
-}
-
-static Chan*
-audioattach(char *param)
-{
- return devattach('A', param);
-}
-
-static Walkqid*
-audiowalk(Chan *c, Chan *nc, char **name, int nname)
-{
- return devwalk(c, nc, name, nname, audiodir, nelem(audiodir), devgen);
-}
-
-static int
-audiostat(Chan *c, uchar *db, int n)
-{
- return devstat(c, db, n, audiodir, nelem(audiodir), devgen);
-}
-
-static Chan*
-audioopen(Chan *c, int omode)
-{
- int amode;
-
- switch((ulong)c->qid.path) {
- default:
- error(Eperm);
- break;
-
- case Qvolume:
- case Qdir:
- break;
-
- case Qaudio:
- amode = Awrite;
- if((omode&7) == OREAD)
- amode = Aread;
- aqlock(&audio);
- if(waserror()){
- aqunlock(&audio);
- nexterror();
- }
- if(audio.amode != Aclosed)
- error(Einuse);
- audiodevopen();
- audio.amode = amode;
- poperror();
- aqunlock(&audio);
- break;
- }
- c = devopen(c, omode, audiodir, nelem(audiodir), devgen);
- c->mode = openmode(omode);
- c->flag |= COPEN;
- c->offset = 0;
-
- return c;
-}
-
-static void
-audioclose(Chan *c)
-{
- switch((ulong)c->qid.path) {
- default:
- error(Eperm);
- break;
-
- case Qdir:
- case Qvolume:
- break;
-
- case Qaudio:
- if(c->flag & COPEN) {
- aqlock(&audio);
- audiodevclose();
- audio.amode = Aclosed;
- aqunlock(&audio);
- }
- break;
- }
-}
-
-static long
-audioread(Chan *c, void *v, long n, vlong off)
-{
- int liv, riv, lov, rov;
- long m;
- char buf[300];
- int j;
- ulong offset = off;
- char *a;
-
- a = v;
- switch((ulong)c->qid.path) {
- default:
- error(Eperm);
- break;
-
- case Qdir:
- return devdirread(c, a, n, audiodir, nelem(audiodir), devgen);
-
- case Qaudio:
- if(audio.amode != Aread)
- error(Emode);
- aqlock(&audio);
- if(waserror()){
- aqunlock(&audio);
- nexterror();
- }
- n = audiodevread(v, n);
- poperror();
- aqunlock(&audio);
- break;
-
- case Qvolume:
- j = 0;
- buf[0] = 0;
- for(m=0; volumes[m].name; m++){
- lov = -1;
- rov = -1;
- audiodevgetvol(m, &lov, &rov);
- if(lov < 0 && rov < 0)
- continue;
- liv = lov;
- riv = rov;
- j += snprint(buf+j, sizeof(buf)-j, "%s", volumes[m].name);
- if((volumes[m].flag & Fmono) || (liv==riv && lov==rov)){
- if((volumes[m].flag&(Fin|Fout))==(Fin|Fout) && liv==lov)
- j += snprint(buf+j, sizeof(buf)-j, " %d", liv);
- else{
- if(volumes[m].flag & Fin)
- j += snprint(buf+j, sizeof(buf)-j,
- " in %d", liv);
- if(volumes[m].flag & Fout)
- j += snprint(buf+j, sizeof(buf)-j,
- " out %d", lov);
- }
- }else{
- if((volumes[m].flag&(Fin|Fout))==(Fin|Fout) &&
- liv==lov && riv==rov)
- j += snprint(buf+j, sizeof(buf)-j,
- " left %d right %d",
- liv, riv);
- else{
- if(volumes[m].flag & Fin)
- j += snprint(buf+j, sizeof(buf)-j,
- " in left %d right %d",
- liv, riv);
- if(volumes[m].flag & Fout)
- j += snprint(buf+j, sizeof(buf)-j,
- " out left %d right %d",
- lov, rov);
- }
- }
- j += snprint(buf+j, sizeof(buf)-j, "\n");
- }
- return readstr(offset, a, n, buf);
- }
- return n;
-}
-
-static long
-audiowrite(Chan *c, void *vp, long n, vlong off)
-{
- long m;
- int i, v, left, right, in, out;
- Cmdbuf *cb;
-
- USED(off);
- switch((ulong)c->qid.path) {
- default:
- error(Eperm);
- break;
-
- case Qvolume:
- v = Vaudio;
- left = 1;
- right = 1;
- in = 1;
- out = 1;
- cb = parsecmd(vp, n);
- if(waserror()){
- free(cb);
- nexterror();
- }
-
- for(i = 0; i < cb->nf; i++){
- /*
- * a number is volume
- */
- if(cb->f[i][0] >= '0' && cb->f[i][0] <= '9') {
- m = strtoul(cb->f[i], 0, 10);
- USED(in);
- if(!out)
- goto cont0;
- if(left && right)
- audiodevsetvol(v, m, m);
- else if(left)
- audiodevsetvol(v, m, -1);
- else if(right)
- audiodevsetvol(v, -1, m);
- goto cont0;
- }
-
- for(m=0; volumes[m].name; m++) {
- if(strcmp(cb->f[i], volumes[m].name) == 0) {
- v = m;
- in = 1;
- out = 1;
- left = 1;
- right = 1;
- goto cont0;
- }
- }
-
- if(strcmp(cb->f[i], "reset") == 0) {
- resetlevel();
- goto cont0;
- }
- if(strcmp(cb->f[i], "in") == 0) {
- in = 1;
- out = 0;
- goto cont0;
- }
- if(strcmp(cb->f[i], "out") == 0) {
- in = 0;
- out = 1;
- goto cont0;
- }
- if(strcmp(cb->f[i], "left") == 0) {
- left = 1;
- right = 0;
- goto cont0;
- }
- if(strcmp(cb->f[i], "right") == 0) {
- left = 0;
- right = 1;
- goto cont0;
- }
- error(Evolume);
- break;
- cont0:;
- }
- free(cb);
- poperror();
- break;
-
- case Qaudio:
- if(audio.amode != Awrite)
- error(Emode);
- aqlock(&audio);
- if(waserror()){
- aqunlock(&audio);
- nexterror();
- }
- n = audiodevwrite(vp, n);
- poperror();
- aqunlock(&audio);
- break;
- }
- return n;
-}
-
-void
-audioswab(uchar *a, uint n)
-{
- ulong *p, *ep, b;
-
- p = (ulong*)a;
- ep = p + (n>>2);
- while(p < ep) {
- b = *p;
- b = (b>>24) | (b<<24) |
- ((b&0xff0000) >> 8) |
- ((b&0x00ff00) << 8);
- *p++ = b;
- }
-}
-
-Dev audiodevtab = {
- 'A',
- "audio",
-
- devreset,
- audioinit,
- devshutdown,
- audioattach,
- audiowalk,
- audiostat,
- audioopen,
- devcreate,
- audioclose,
- audioread,
- devbread,
- audiowrite,
- devbwrite,
- devremove,
- devwstat,
-};
--- a/kern/devaudio.h
+++ /dev/null
@@ -1,25 +1,0 @@
-enum
-{
- Fmono = 1,
- Fin = 2,
- Fout = 4,
-
- Vaudio = 0,
- Vsynth,
- Vcd,
- Vline,
- Vmic,
- Vspeaker,
- Vtreb,
- Vbass,
- Vspeed,
- Vpcm,
- Nvol,
-};
-
-void audiodevopen(void);
-void audiodevclose(void);
-int audiodevread(void*, int);
-int audiodevwrite(void*, int);
-void audiodevgetvol(int, int*, int*);
-void audiodevsetvol(int, int, int);
--- a/kern/devcons.c
+++ b/kern/devcons.c
@@ -6,8 +6,6 @@
#include "keyboard.h"
-#include <authsrv.h>
-
#undef write
#undef read
@@ -365,7 +363,7 @@
"cons", {Qcons}, 0, 0660,
"consctl", {Qconsctl}, 0, 0220,
"drivers", {Qdrivers}, 0, 0444,
- "hostdomain", {Qhostdomain}, DOMLEN, 0664,
+ "hostdomain", {Qhostdomain}, 48, 0664,
"hostowner", {Qhostowner}, 0, 0664,
"kmesg", {Qkmesg}, 0, 0440,
"kprint", {Qkprint, 0, QTEXCL}, 0, DMEXCL|0440,
--- a/kern/devdraw.c
+++ /dev/null
@@ -1,2130 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <memlayer.h>
-#include <cursor.h>
-#include "screen.h"
-
-enum
-{
- Qtopdir = 0,
- Qnew,
- Qwinname,
- Q3rd,
- Q2nd,
- Qcolormap,
- Qctl,
- Qdata,
- Qrefresh,
-};
-
-/*
- * Qid path is:
- * 4 bits of file type (qids above)
- * 24 bits of mux slot number +1; 0 means not attached to client
- */
-#define QSHIFT 4 /* location in qid of client # */
-
-#define QID(q) ((((ulong)(q).path)&0x0000000F)>>0)
-#define CLIENTPATH(q) ((((ulong)q)&0x7FFFFFF0)>>QSHIFT)
-#define CLIENT(q) CLIENTPATH((q).path)
-
-#define NHASH (1<<5)
-#define HASHMASK (NHASH-1)
-#define IOUNIT (64*1024)
-
-typedef struct Client Client;
-typedef struct Draw Draw;
-typedef struct DImage DImage;
-typedef struct DScreen DScreen;
-typedef struct CScreen CScreen;
-typedef struct FChar FChar;
-typedef struct Refresh Refresh;
-typedef struct Refx Refx;
-typedef struct DName DName;
-
-struct Draw
-{
- int clientid;
- int nclient;
- Client** client;
- int nname;
- DName* name;
- int vers;
- int softscreen;
-};
-
-struct Client
-{
- Ref r;
- DImage* dimage[NHASH];
- CScreen* cscreen;
- Refresh* refresh;
- Rendez refrend;
- QLock refq;
- uchar* readdata;
- int nreaddata;
- int busy;
- int clientid;
- int slot;
- int refreshme;
- int infoid;
- int op;
-};
-
-struct Refresh
-{
- DImage* dimage;
- Rectangle r;
- Refresh* next;
-};
-
-struct Refx
-{
- Client* client;
- DImage* dimage;
-};
-
-struct DName
-{
- char *name;
- Client *client;
- DImage* dimage;
- int vers;
-};
-
-struct FChar
-{
- int minx; /* left edge of bits */
- int maxx; /* right edge of bits */
- uchar miny; /* first non-zero scan-line */
- uchar maxy; /* last non-zero scan-line + 1 */
- schar left; /* offset of baseline */
- uchar width; /* width of baseline */
-};
-
-/*
- * Reference counts in DImages:
- * one per open by original client
- * one per screen image or fill
- * one per image derived from this one by name
- */
-struct DImage
-{
- int id;
- int ref;
- char *name;
- int vers;
- Memimage* image;
- int ascent;
- int nfchar;
- FChar* fchar;
- DScreen* dscreen; /* 0 if not a window */
- DImage* fromname; /* image this one is derived from, by name */
- DImage* next;
-};
-
-struct CScreen
-{
- DScreen* dscreen;
- CScreen* next;
-};
-
-struct DScreen
-{
- int id;
- int public;
- int ref;
- DImage *dimage;
- DImage *dfill;
- Memscreen* screen;
- Client* owner;
- DScreen* next;
-};
-
-static Draw sdraw;
- QLock drawlock;
-
-static Memimage *screenimage;
-static DImage* screendimage;
-static char screenname[40];
-static int screennameid;
-
-static Rectangle flushrect;
-static int waste;
-static DScreen* dscreen;
-extern void flushmemscreen(Rectangle);
- void drawmesg(Client*, void*, int);
- void drawuninstall(Client*, int);
- void drawfreedimage(DImage*);
- Client* drawclientofpath(ulong);
- DImage* allocdimage(Memimage*);
-
-static char Enodrawimage[] = "unknown id for draw image";
-static char Enodrawscreen[] = "unknown id for draw screen";
-static char Eshortdraw[] = "short draw message";
-static char Eshortread[] = "draw read too short";
-static char Eimageexists[] = "image id in use";
-static char Escreenexists[] = "screen id in use";
-static char Edrawmem[] = "image memory allocation failed";
-static char Ereadoutside[] = "readimage outside image";
-static char Ewriteoutside[] = "writeimage outside image";
-static char Enotfont[] = "image not a font";
-static char Eindex[] = "character index out of range";
-static char Enoclient[] = "no such draw client";
-static char Enameused[] = "image name in use";
-static char Enoname[] = "no image with that name";
-static char Eoldname[] = "named image no longer valid";
-static char Enamed[] = "image already has name";
-static char Ewrongname[] = "wrong name for image";
-
-static void
-dlock(void)
-{
- qlock(&drawlock);
-}
-
-static void
-dunlock(void)
-{
- qunlock(&drawlock);
-}
-
-static int
-drawgen(Chan *c, char *n, Dirtab *d, int nd, int s, Dir *dp)
-{
- int t;
- Qid q;
- ulong path;
- Client *cl;
-
- USED(n);
- USED(d);
- USED(nd);
-
- q.vers = 0;
-
- if(s == DEVDOTDOT){
- switch(QID(c->qid)){
- case Qtopdir:
- case Q2nd:
- mkqid(&q, Qtopdir, 0, QTDIR);
- devdir(c, q, "#i", 0, eve, 0500, dp);
- break;
- case Q3rd:
- cl = drawclientofpath(c->qid.path);
- if(cl == nil)
- strcpy(up->genbuf, "??");
- else
- sprint(up->genbuf, "%d", cl->clientid);
- mkqid(&q, Q2nd, 0, QTDIR);
- devdir(c, q, up->genbuf, 0, eve, 0500, dp);
- break;
- default:
- panic("drawwalk %llux", c->qid.path);
- }
- return 1;
- }
-
- /*
- * Top level directory contains the name of the device.
- */
- t = QID(c->qid);
- switch(t){
- case Qtopdir:
- if(s == 0){
- mkqid(&q, Q2nd, 0, QTDIR);
- devdir(c, q, "draw", 0, eve, 0555, dp);
- return 1;
- }
- if(s == 1){
- case Qwinname:
- mkqid(&q, Qwinname, 0, QTFILE);
- devdir(c, q, "winname", 0, eve, 0444, dp);
- return 1;
- }
- return -1;
- }
-
- /*
- * Second level contains "new" plus all the clients.
- */
- switch(t){
- case Q2nd:
- if(s == 0){
- case Qnew:
- mkqid(&q, Qnew, 0, QTFILE);
- devdir(c, q, "new", 0, eve, 0666, dp);
- return 1;
- }
- if(s <= sdraw.nclient){
- cl = sdraw.client[s-1];
- if(cl == nil)
- return 0;
- sprint(up->genbuf, "%d", cl->clientid);
- mkqid(&q, (s<<QSHIFT)|Q3rd, 0, QTDIR);
- devdir(c, q, up->genbuf, 0, eve, 0555, dp);
- return 1;
- }
- return -1;
- }
-
- /*
- * Third level.
- */
- path = c->qid.path&~((1<<QSHIFT)-1); /* slot component */
- q.vers = c->qid.vers;
- q.type = QTFILE;
- switch(s){
- case 0:
- q.path = path|Qcolormap;
- devdir(c, q, "colormap", 0, eve, 0600, dp);
- break;
- case 1:
- q.path = path|Qctl;
- devdir(c, q, "ctl", 0, eve, 0600, dp);
- break;
- case 2:
- q.path = path|Qdata;
- devdir(c, q, "data", 0, eve, 0600, dp);
- break;
- case 3:
- q.path = path|Qrefresh;
- devdir(c, q, "refresh", 0, eve, 0400, dp);
- break;
- default:
- return -1;
- }
- return 1;
-}
-
-static
-int
-drawrefactive(void *a)
-{
- Client *c;
-
- c = a;
- return c->refreshme || c->refresh!=0;
-}
-
-static
-void
-drawrefreshscreen(DImage *l, Client *client)
-{
- while(l != nil && l->dscreen == nil)
- l = l->fromname;
- if(l != nil && l->dscreen->owner != client)
- l->dscreen->owner->refreshme = 1;
-}
-
-static
-void
-drawrefresh(Memimage *i, Rectangle r, void *v)
-{
- Refx *x;
- DImage *d;
- Client *c;
- Refresh *ref;
-
- USED(i);
-
- if(v == 0)
- return;
- x = v;
- c = x->client;
- d = x->dimage;
- for(ref=c->refresh; ref; ref=ref->next)
- if(ref->dimage == d){
- combinerect(&ref->r, r);
- return;
- }
- ref = malloc(sizeof(Refresh));
- if(ref){
- ref->dimage = d;
- ref->r = r;
- ref->next = c->refresh;
- c->refresh = ref;
- }
-}
-
-static void
-addflush(Rectangle r)
-{
- int abb, ar, anbb;
- Rectangle nbb;
-
- if(sdraw.softscreen==0 || screenimage == nil || !rectclip(&r, screenimage->r))
- return;
- if(flushrect.min.x >= flushrect.max.x){
- flushrect = r;
- waste = 0;
- return;
- }
- nbb = flushrect;
- combinerect(&nbb, r);
- ar = Dx(r)*Dy(r);
- abb = Dx(flushrect)*Dy(flushrect);
- anbb = Dx(nbb)*Dy(nbb);
- /*
- * Area of new waste is area of new bb minus area of old bb,
- * less the area of the new segment, which we assume is not waste.
- * This could be negative, but that's OK.
- */
- waste += anbb-abb - ar;
- if(waste < 0)
- waste = 0;
- /*
- * absorb if:
- * total area is small
- * waste is less than half total area
- * rectangles touch
- */
- if(anbb<=1024 || waste*2<anbb || rectXrect(flushrect, r)){
- flushrect = nbb;
- return;
- }
- /* emit current state */
- if(flushrect.min.x < flushrect.max.x)
- flushmemscreen(flushrect);
- flushrect = r;
- waste = 0;
-}
-
-static
-void
-dstflush(int dstid, Memimage *dst, Rectangle r)
-{
- Memlayer *l;
-
- if(dstid == 0){
- combinerect(&flushrect, r);
- return;
- }
- if(screenimage == nil || dst == nil || (l = dst->layer) == nil)
- return;
- do{
- if(l->screen->image->data != screenimage->data)
- return;
- r = rectaddpt(r, l->delta);
- l = l->screen->image->layer;
- }while(l);
- addflush(r);
-}
-
-void
-drawflush(void)
-{
- if(screenimage && flushrect.min.x < flushrect.max.x)
- flushmemscreen(flushrect);
- flushrect = Rect(10000, 10000, -10000, -10000);
-}
-
-int
-drawcmp(char *a, char *b, int n)
-{
- if(strlen(a) != n)
- return 1;
- return memcmp(a, b, n);
-}
-
-DName*
-drawlookupname(int n, char *str)
-{
- DName *name, *ename;
-
- name = sdraw.name;
- ename = &name[sdraw.nname];
- for(; name<ename; name++)
- if(drawcmp(name->name, str, n) == 0)
- return name;
- return 0;
-}
-
-int
-drawgoodname(DImage *d)
-{
- DName *n;
-
- /* if window, validate the screen's own images */
- if(d->dscreen)
- if(drawgoodname(d->dscreen->dimage) == 0
- || drawgoodname(d->dscreen->dfill) == 0)
- return 0;
- if(d->name == nil)
- return 1;
- n = drawlookupname(strlen(d->name), d->name);
- if(n==nil || n->vers!=d->vers)
- return 0;
- return 1;
-}
-
-DImage*
-drawlookup(Client *client, int id, int checkname)
-{
- DImage *d;
-
- d = client->dimage[id&HASHMASK];
- while(d){
- if(d->id == id){
- if(checkname && !drawgoodname(d))
- error(Eoldname);
- return d;
- }
- d = d->next;
- }
- return 0;
-}
-
-DScreen*
-drawlookupdscreen(int id)
-{
- DScreen *s;
-
- s = dscreen;
- while(s){
- if(s->id == id)
- return s;
- s = s->next;
- }
- return 0;
-}
-
-DScreen*
-drawlookupscreen(Client *client, int id, CScreen **cs)
-{
- CScreen *s;
-
- s = client->cscreen;
- while(s){
- if(s->dscreen->id == id){
- *cs = s;
- return s->dscreen;
- }
- s = s->next;
- }
- error(Enodrawscreen);
- return 0;
-}
-
-DImage*
-allocdimage(Memimage *i)
-{
- DImage *d;
-
- d = malloc(sizeof(DImage));
- if(d == 0)
- return 0;
- d->ref = 1;
- d->name = 0;
- d->vers = 0;
- d->image = i;
- d->dscreen = 0;
- d->nfchar = 0;
- d->fchar = 0;
- d->fromname = 0;
- return d;
-}
-
-Memimage*
-drawinstall(Client *client, int id, Memimage *i, DScreen *dscreen)
-{
- DImage *d;
-
- d = allocdimage(i);
- if(d == 0)
- return 0;
- d->id = id;
- d->dscreen = dscreen;
- d->next = client->dimage[id&HASHMASK];
- client->dimage[id&HASHMASK] = d;
- return i;
-}
-
-Memscreen*
-drawinstallscreen(Client *client, DScreen *d, int id, DImage *dimage, DImage *dfill, int public)
-{
- Memscreen *s;
- CScreen *c;
-
- c = malloc(sizeof(CScreen));
- if(dimage && dimage->image && dimage->image->chan == 0)
- panic("bad image %p in drawinstallscreen", dimage->image);
-
- if(c == 0)
- return 0;
- if(d == 0){
- d = malloc(sizeof(DScreen));
- if(d == 0){
- free(c);
- return 0;
- }
- s = malloc(sizeof(Memscreen));
- if(s == 0){
- free(c);
- free(d);
- return 0;
- }
- s->frontmost = 0;
- s->rearmost = 0;
- d->dimage = dimage;
- if(dimage){
- s->image = dimage->image;
- dimage->ref++;
- }
- d->dfill = dfill;
- if(dfill){
- s->fill = dfill->image;
- dfill->ref++;
- }
- d->ref = 0;
- d->id = id;
- d->screen = s;
- d->public = public;
- d->next = dscreen;
- d->owner = client;
- dscreen = d;
- }
- c->dscreen = d;
- d->ref++;
- c->next = client->cscreen;
- client->cscreen = c;
- return d->screen;
-}
-
-void
-drawdelname(DName *name)
-{
- int i;
-
- free(name->name);
- i = name-sdraw.name;
- memmove(name, name+1, (sdraw.nname-(i+1))*sizeof(DName));
- sdraw.nname--;
-}
-
-void
-drawfreedscreen(DScreen *this)
-{
- DScreen *ds, *next;
-
- this->ref--;
- if(this->ref < 0)
- print("negative ref in drawfreedscreen\n");
- if(this->ref > 0)
- return;
- ds = dscreen;
- if(ds == this){
- dscreen = this->next;
- goto Found;
- }
- while((next = ds->next) != nil){
- if(next == this){
- ds->next = this->next;
- goto Found;
- }
- ds = next;
- }
- error(Enodrawimage);
-
- Found:
- if(this->dimage)
- drawfreedimage(this->dimage);
- if(this->dfill)
- drawfreedimage(this->dfill);
- free(this->screen);
- free(this);
-}
-
-void
-drawfreedimage(DImage *dimage)
-{
- int i;
- Memimage *l;
- DScreen *ds;
-
- dimage->ref--;
- if(dimage->ref < 0)
- print("negative ref in drawfreedimage\n");
- if(dimage->ref > 0)
- return;
-
- /* any names? */
- for(i=0; i<sdraw.nname; )
- if(sdraw.name[i].dimage == dimage)
- drawdelname(sdraw.name+i);
- else
- i++;
- if(dimage->fromname){ /* acquired by name; owned by someone else*/
- drawfreedimage(dimage->fromname);
- goto Return;
- }
- ds = dimage->dscreen;
- if(ds){
- l = dimage->image;
- if(screenimage && l->data == screenimage->data)
- addflush(l->layer->screenr);
- if(l->layer->refreshfn == drawrefresh) /* else true owner will clean up */
- free(l->layer->refreshptr);
- l->layer->refreshptr = nil;
- if(drawgoodname(dimage))
- memldelete(l);
- else
- memlfree(l);
- drawfreedscreen(ds);
- }else
- freememimage(dimage->image);
- Return:
- free(dimage->fchar);
- free(dimage);
-}
-
-void
-drawuninstallscreen(Client *client, CScreen *this)
-{
- CScreen *cs, *next;
-
- cs = client->cscreen;
- if(cs == this){
- client->cscreen = this->next;
- drawfreedscreen(this->dscreen);
- free(this);
- return;
- }
- while((next = cs->next) != nil){
- if(next == this){
- cs->next = this->next;
- drawfreedscreen(this->dscreen);
- free(this);
- return;
- }
- cs = next;
- }
-}
-
-void
-drawuninstall(Client *client, int id)
-{
- DImage *d, *next;
-
- d = client->dimage[id&HASHMASK];
- if(d == 0)
- error(Enodrawimage);
- if(d->id == id){
- client->dimage[id&HASHMASK] = d->next;
- drawfreedimage(d);
- return;
- }
- while((next = d->next) != nil){
- if(next->id == id){
- d->next = next->next;
- drawfreedimage(next);
- return;
- }
- d = next;
- }
- error(Enodrawimage);
-}
-
-void
-drawaddname(Client *client, DImage *di, int n, char *str)
-{
- DName *name, *ename, *new, *t;
-
- name = sdraw.name;
- ename = &name[sdraw.nname];
- for(; name<ename; name++)
- if(drawcmp(name->name, str, n) == 0)
- error(Enameused);
- t = smalloc((sdraw.nname+1)*sizeof(DName));
- memmove(t, sdraw.name, sdraw.nname*sizeof(DName));
- free(sdraw.name);
- sdraw.name = t;
- new = &sdraw.name[sdraw.nname++];
- new->name = smalloc(n+1);
- memmove(new->name, str, n);
- new->name[n] = 0;
- new->dimage = di;
- new->client = client;
- new->vers = ++sdraw.vers;
-}
-
-Client*
-drawnewclient(void)
-{
- Client *cl, **cp;
- int i;
-
- for(i=0; i<sdraw.nclient; i++){
- cl = sdraw.client[i];
- if(cl == 0)
- break;
- }
- if(i == sdraw.nclient){
- cp = malloc((sdraw.nclient+1)*sizeof(Client*));
- if(cp == 0)
- return 0;
- memmove(cp, sdraw.client, sdraw.nclient*sizeof(Client*));
- free(sdraw.client);
- sdraw.client = cp;
- sdraw.nclient++;
- cp[i] = 0;
- }
- cl = malloc(sizeof(Client));
- if(cl == 0)
- return 0;
- memset(cl, 0, sizeof(Client));
- cl->slot = i;
- cl->clientid = ++sdraw.clientid;
- cl->op = SoverD;
- sdraw.client[i] = cl;
- return cl;
-}
-
-static int
-drawclientop(Client *cl)
-{
- int op;
-
- op = cl->op;
- cl->op = SoverD;
- return op;
-}
-
-int
-drawhasclients(void)
-{
- /*
- * if draw has ever been used, we can't resize the frame buffer,
- * even if all clients have exited (nclients is cumulative); it's too
- * hard to make work.
- */
- return sdraw.nclient != 0;
-}
-
-Client*
-drawclientofpath(ulong path)
-{
- Client *cl;
- int slot;
-
- slot = CLIENTPATH(path);
- if(slot == 0)
- return nil;
- cl = sdraw.client[slot-1];
- if(cl==0 || cl->clientid==0)
- return nil;
- return cl;
-}
-
-
-Client*
-drawclient(Chan *c)
-{
- Client *client;
-
- client = drawclientofpath(c->qid.path);
- if(client == nil)
- error(Enoclient);
- return client;
-}
-
-Memimage*
-drawimage(Client *client, uchar *a)
-{
- DImage *d;
-
- d = drawlookup(client, BGLONG(a), 1);
- if(d == nil)
- error(Enodrawimage);
- return d->image;
-}
-
-void
-drawrectangle(Rectangle *r, uchar *a)
-{
- r->min.x = BGLONG(a+0*4);
- r->min.y = BGLONG(a+1*4);
- r->max.x = BGLONG(a+2*4);
- r->max.y = BGLONG(a+3*4);
-}
-
-void
-drawpoint(Point *p, uchar *a)
-{
- p->x = BGLONG(a+0*4);
- p->y = BGLONG(a+1*4);
-}
-
-Point
-drawchar(Memimage *dst, Memimage *rdst, Point p, Memimage *src, Point *sp, DImage *font, int index, int op)
-{
- FChar *fc;
- Rectangle r;
- Point sp1;
- static Memimage *tmp;
-
- fc = &font->fchar[index];
- r.min.x = p.x+fc->left;
- r.min.y = p.y-(font->ascent-fc->miny);
- r.max.x = r.min.x+(fc->maxx-fc->minx);
- r.max.y = r.min.y+(fc->maxy-fc->miny);
- sp1.x = sp->x+fc->left;
- sp1.y = sp->y+fc->miny;
-
- /*
- * If we're drawing greyscale fonts onto a VGA screen,
- * it's very costly to read the screen memory to do the
- * alpha blending inside memdraw. If this is really a stringbg,
- * then rdst is the bg image (in main memory) which we can
- * refer to for the underlying dst pixels instead of reading dst
- * directly.
- */
- if(ishwimage(dst) && !ishwimage(rdst) && font->image->depth > 1){
- if(tmp == nil || tmp->chan != dst->chan || Dx(tmp->r) < Dx(r) || Dy(tmp->r) < Dy(r)){
- if(tmp)
- freememimage(tmp);
- tmp = allocmemimage(Rect(0,0,Dx(r),Dy(r)), dst->chan);
- if(tmp == nil)
- goto fallback;
- }
- memdraw(tmp, Rect(0,0,Dx(r),Dy(r)), rdst, r.min, memopaque, ZP, S);
- memdraw(tmp, Rect(0,0,Dx(r),Dy(r)), src, sp1, font->image, Pt(fc->minx, fc->miny), op);
- memdraw(dst, r, tmp, ZP, memopaque, ZP, S);
- }else{
- fallback:
- memdraw(dst, r, src, sp1, font->image, Pt(fc->minx, fc->miny), op);
- }
-
- p.x += fc->width;
- sp->x += fc->width;
- return p;
-}
-
-static DImage*
-makescreenimage(void)
-{
- int width, depth;
- ulong chan;
- DImage *di;
- Memdata *md;
- Memimage *i;
- Rectangle r;
-
- if((md = attachscreen(&r, &chan, &depth, &width, &sdraw.softscreen)) == nil)
- return nil;
- assert(md->ref > 0);
- if((i = allocmemimaged(r, chan, md)) == nil){
- if(--md->ref == 0 && md->allocd)
- free(md);
- return nil;
- }
- i->width = width;
- i->clipr = r;
- di = allocdimage(i);
- if(di == nil){
- freememimage(i); /* frees md */
- return nil;
- }
- if(!waserror()){
- snprint(screenname, sizeof screenname, "noborder.screen.%d", ++screennameid);
- drawaddname(nil, di, strlen(screenname), screenname);
- poperror();
- }
- return di;
-}
-
-static int
-initscreenimage(void)
-{
- if(screenimage != nil)
- return 1;
-
- screendimage = makescreenimage();
- if(screendimage == nil)
- return 0;
- screenimage = screendimage->image;
-// iprint("initscreenimage %p %p\n", screendimage, screenimage);
- mouseresize();
- return 1;
-}
-
-void
-deletescreenimage(void)
-{
- if(screenimage){
- /* will be freed via screendimage; disable */
- screenimage->clipr = ZR;
- screenimage = nil;
- }
- if(screendimage){
- drawfreedimage(screendimage);
- screendimage = nil;
- }
-}
-
-void
-resetscreenimage(void)
-{
- initscreenimage();
-}
-
-static Chan*
-drawattach(char *spec)
-{
- if(gscreen == nil)
- screeninit();
- dlock();
- if(!initscreenimage()){
- dunlock();
- error("no frame buffer");
- }
- dunlock();
- return devattach('i', spec);
-}
-
-static Walkqid*
-drawwalk(Chan *c, Chan *nc, char **name, int nname)
-{
- if(screenimage == nil)
- error("no frame buffer");
- return devwalk(c, nc, name, nname, 0, 0, drawgen);
-}
-
-static int
-drawstat(Chan *c, uchar *db, int n)
-{
- return devstat(c, db, n, 0, 0, drawgen);
-}
-
-static Chan*
-drawopen(Chan *c, int omode)
-{
- Client *cl;
- DName *dn;
- DImage *di;
-
- if(c->qid.type & QTDIR){
- c = devopen(c, omode, 0, 0, drawgen);
- c->iounit = IOUNIT;
- }
-
- dlock();
- if(waserror()){
- dunlock();
- nexterror();
- }
-
- if(QID(c->qid) == Qnew){
- cl = drawnewclient();
- if(cl == 0)
- error(Enodev);
- c->qid.path = Qctl|((cl->slot+1)<<QSHIFT);
- }
-
- switch(QID(c->qid)){
- case Qwinname:
- break;
-
- case Qnew:
- break;
-
- case Qctl:
- cl = drawclient(c);
- if(cl->busy)
- error(Einuse);
- cl->busy = 1;
- flushrect = Rect(10000, 10000, -10000, -10000);
- dn = drawlookupname(strlen(screenname), screenname);
- if(dn == 0)
- error("draw: cannot happen 2");
- if(drawinstall(cl, 0, dn->dimage->image, 0) == 0)
- error(Edrawmem);
- di = drawlookup(cl, 0, 0);
- if(di == 0)
- error("draw: cannot happen 1");
- di->vers = dn->vers;
- di->name = smalloc(strlen(screenname)+1);
- strcpy(di->name, screenname);
- di->fromname = dn->dimage;
- di->fromname->ref++;
- incref(&cl->r);
- break;
-
- case Qcolormap:
- case Qdata:
- case Qrefresh:
- cl = drawclient(c);
- incref(&cl->r);
- break;
- }
- dunlock();
- poperror();
- c->mode = openmode(omode);
- c->flag |= COPEN;
- c->offset = 0;
- c->iounit = IOUNIT;
- return c;
-}
-
-static void
-drawclose(Chan *c)
-{
- int i;
- DImage *d, **dp;
- Client *cl;
- Refresh *r;
-
- if(QID(c->qid) < Qcolormap) /* Qtopdir, Qnew, Q3rd, Q2nd have no client */
- return;
- dlock();
- if(waserror()){
- dunlock();
- nexterror();
- }
-
- cl = drawclient(c);
- if(QID(c->qid) == Qctl)
- cl->busy = 0;
- if((c->flag&COPEN) && (decref(&cl->r)==0)){
- while((r = cl->refresh) != nil){
- cl->refresh = r->next;
- free(r);
- }
- /* free names */
- for(i=0; i<sdraw.nname; )
- if(sdraw.name[i].client == cl)
- drawdelname(sdraw.name+i);
- else
- i++;
- while(cl->cscreen)
- drawuninstallscreen(cl, cl->cscreen);
- /* all screens are freed, so now we can free images */
- dp = cl->dimage;
- for(i=0; i<NHASH; i++){
- while((d = *dp) != nil){
- *dp = d->next;
- drawfreedimage(d);
- }
- dp++;
- }
- sdraw.client[cl->slot] = 0;
- drawflush(); /* to erase visible, now dead windows */
- free(cl);
- }
- dunlock();
- poperror();
-}
-
-long
-drawread(Chan *c, void *a, long n, vlong off)
-{
- int index, m;
- ulong red, green, blue;
- Client *cl;
- uchar *p;
- Refresh *r;
- DImage *di;
- Memimage *i;
- ulong offset = off;
- char buf[16];
-
- if(c->qid.type & QTDIR)
- return devdirread(c, a, n, 0, 0, drawgen);
- if(QID(c->qid) == Qwinname)
- return readstr(off, a, n, screenname);
-
- cl = drawclient(c);
- dlock();
- if(waserror()){
- dunlock();
- nexterror();
- }
- switch(QID(c->qid)){
- case Qctl:
- if(n < 12*12)
- error(Eshortread);
- if(cl->infoid < 0)
- error(Enodrawimage);
- if(cl->infoid == 0){
- i = screenimage;
- if(i == nil)
- error(Enodrawimage);
- }else{
- di = drawlookup(cl, cl->infoid, 1);
- if(di == nil)
- error(Enodrawimage);
- i = di->image;
- }
- n = sprint(a, "%11d %11d %11s %11d %11d %11d %11d %11d %11d %11d %11d %11d",
- cl->clientid, cl->infoid, chantostr(buf, i->chan), (i->flags&Frepl)==Frepl,
- i->r.min.x, i->r.min.y, i->r.max.x, i->r.max.y,
- i->clipr.min.x, i->clipr.min.y, i->clipr.max.x, i->clipr.max.y);
- ((char*)a)[n++] = ' ';
- cl->infoid = -1;
- break;
-
- case Qcolormap:
- p = malloc(4*12*256+1);
- if(p == 0)
- error(Enomem);
- m = 0;
- for(index = 0; index < 256; index++){
- getcolor(index, &red, &green, &blue);
- m += sprint((char*)p+m, "%11d %11lud %11lud %11lud\n", index, red>>24, green>>24, blue>>24);
- }
- n = readstr(offset, a, n, (char*)p);
- free(p);
- break;
-
- case Qdata:
- if(cl->readdata == nil)
- error("no draw data");
- if(n < cl->nreaddata)
- error(Eshortread);
- n = cl->nreaddata;
- memmove(a, cl->readdata, cl->nreaddata);
- free(cl->readdata);
- cl->readdata = nil;
- break;
-
- case Qrefresh:
- if(n < 5*4)
- error(Ebadarg);
- for(;;){
- if(cl->refreshme || cl->refresh)
- break;
- dunlock();
- if(waserror()){
- dlock();
- nexterror();
- }
- qlock(&cl->refq);
- if(waserror()){
- qunlock(&cl->refq);
- nexterror();
- }
- sleep(&cl->refrend, drawrefactive, cl);
- poperror();
- qunlock(&cl->refq);
- poperror();
- dlock();
- }
- p = a;
- while(cl->refresh && n>=5*4){
- r = cl->refresh;
- BPLONG(p+0*4, r->dimage->id);
- BPLONG(p+1*4, r->r.min.x);
- BPLONG(p+2*4, r->r.min.y);
- BPLONG(p+3*4, r->r.max.x);
- BPLONG(p+4*4, r->r.max.y);
- cl->refresh = r->next;
- free(r);
- p += 5*4;
- n -= 5*4;
- }
- cl->refreshme = 0;
- n = p-(uchar*)a;
- break;
- }
- dunlock();
- poperror();
- return n;
-}
-
-void
-drawwakeall(void)
-{
- Client *cl;
- int i;
-
- for(i=0; i<sdraw.nclient; i++){
- cl = sdraw.client[i];
- if(cl && (cl->refreshme || cl->refresh))
- wakeup(&cl->refrend);
- }
-}
-
-static long
-drawwrite(Chan *c, void *a, long n, vlong off)
-{
- char buf[128], *fields[4], *q;
- Client *cl;
- int i, m, red, green, blue, x;
-
- USED(off);
-
- if(c->qid.type & QTDIR)
- error(Eisdir);
- cl = drawclient(c);
- dlock();
- if(waserror()){
- drawwakeall();
- dunlock();
- nexterror();
- }
- switch(QID(c->qid)){
- case Qctl:
- if(n != 4)
- error("unknown draw control request");
- cl->infoid = BGLONG((uchar*)a);
- break;
-
- case Qcolormap:
- m = n;
- n = 0;
- while(m > 0){
- x = m;
- if(x > sizeof(buf)-1)
- x = sizeof(buf)-1;
- q = memccpy(buf, a, '\n', x);
- if(q == 0)
- break;
- i = q-buf;
- n += i;
- a = (char*)a + i;
- m -= i;
- *q = 0;
- if(tokenize(buf, fields, nelem(fields)) != 4)
- error(Ebadarg);
- i = strtoul(fields[0], 0, 0);
- red = strtoul(fields[1], 0, 0);
- green = strtoul(fields[2], 0, 0);
- blue = strtoul(fields[3], &q, 0);
- if(fields[3] == q)
- error(Ebadarg);
- if(red>255 || green>255 || blue>255 || i<0 || i>255)
- error(Ebadarg);
- red |= red<<8;
- red |= red<<16;
- green |= green<<8;
- green |= green<<16;
- blue |= blue<<8;
- blue |= blue<<16;
- setcolor(i, red, green, blue);
- }
- break;
-
- case Qdata:
- drawmesg(cl, a, n);
- drawwakeall();
- break;
-
- default:
- error(Ebadusefd);
- }
- dunlock();
- poperror();
- return n;
-}
-
-uchar*
-drawcoord(uchar *p, uchar *maxp, int oldx, int *newx)
-{
- int b, x;
-
- if(p >= maxp)
- error(Eshortdraw);
- b = *p++;
- x = b & 0x7F;
- if(b & 0x80){
- if(p+1 >= maxp)
- error(Eshortdraw);
- x |= *p++ << 7;
- x |= *p++ << 15;
- if(x & (1<<22))
- x |= ~0<<23;
- }else{
- if(b & 0x40)
- x |= ~0<<7;
- x += oldx;
- }
- *newx = x;
- return p;
-}
-
-static void
-printmesg(char *fmt, uchar *a, int plsprnt)
-{
- char buf[256];
- char *p, *q;
- int s;
-
- if(1|| plsprnt==0){
- USED(s);
- return;
- }
- q = buf;
- *q++ = *a++;
- for(p=fmt; *p; p++){
- switch(*p){
- case 'l':
- q += sprint(q, " %ld", (long)BGLONG(a));
- a += 4;
- break;
- case 'L':
- q += sprint(q, " %.8lux", (ulong)BGLONG(a));
- a += 4;
- break;
- case 'R':
- q += sprint(q, " [%d %d %d %d]", BGLONG(a), BGLONG(a+4), BGLONG(a+8), BGLONG(a+12));
- a += 16;
- break;
- case 'P':
- q += sprint(q, " [%d %d]", BGLONG(a), BGLONG(a+4));
- a += 8;
- break;
- case 'b':
- q += sprint(q, " %d", *a++);
- break;
- case 's':
- q += sprint(q, " %d", BGSHORT(a));
- a += 2;
- break;
- case 'S':
- q += sprint(q, " %.4ux", BGSHORT(a));
- a += 2;
- break;
- case 'z':
- q += sprint(q, " %.*q", (int)*a, (char*)(a+1));
- a += 1 + *a;
- break;
- }
- }
- *q++ = '\n';
- *q = 0;
- iprint("%.*s", (int)(q-buf), buf);
-}
-
-void
-drawmesg(Client *client, void *av, int n)
-{
- int c, repl, m, y, dstid, scrnid, ni, ci, j, nw, e0, e1, op, ox, oy, oesize, esize, doflush;
- uchar *u, *a, refresh;
- char *fmt;
- ulong value, chan;
- Rectangle r, clipr;
- Point p, q, *pp, sp;
- Memimage *i, *bg, *dst, *src, *mask;
- Memimage *l, **lp;
- Memscreen *scrn;
- DImage *font, *ll, *di, *ddst, *dsrc;
- DName *dn;
- DScreen *dscrn;
- FChar *fc;
- Refx *refx;
- CScreen *cs;
- Refreshfn reffn;
-
- a = av;
- m = 0;
- fmt = nil;
- if(waserror()){
- if(fmt) printmesg(fmt, a, 1);
- /* iprint("error: %s\n", up->errstr); */
- nexterror();
- }
- while((n-=m) > 0){
- USED(fmt);
- a += m;
- switch(*a){
- default:
- error("bad draw command");
- /* new allocate: 'b' id[4] screenid[4] refresh[1] chan[4] repl[1] R[4*4] clipR[4*4] rrggbbaa[4] */
- case 'b':
- printmesg(fmt="LLbLbRRL", a, 0);
- m = 1+4+4+1+4+1+4*4+4*4+4;
- if(n < m)
- error(Eshortdraw);
- dstid = BGLONG(a+1);
- scrnid = BGLONG(a+5);
- refresh = a[9];
- chan = BGLONG(a+10);
- repl = a[14];
- drawrectangle(&r, a+15);
- drawrectangle(&clipr, a+31);
- value = BGLONG(a+47);
- if(drawlookup(client, dstid, 0))
- error(Eimageexists);
- if(scrnid){
- dscrn = drawlookupscreen(client, scrnid, &cs);
- scrn = dscrn->screen;
- if(repl || chan!=scrn->image->chan)
- error("image parameters incompatible with screen");
- reffn = nil;
- switch(refresh){
- case Refbackup:
- break;
- case Refnone:
- reffn = memlnorefresh;
- break;
- case Refmesg:
- reffn = drawrefresh;
- break;
- default:
- error("unknown refresh method");
- }
- l = memlalloc(scrn, r, reffn, 0, value);
- if(l == 0)
- error(Edrawmem);
- addflush(l->layer->screenr);
- l->clipr = clipr;
- rectclip(&l->clipr, r);
- if(drawinstall(client, dstid, l, dscrn) == 0){
- memldelete(l);
- error(Edrawmem);
- }
- dscrn->ref++;
- if(reffn){
- refx = nil;
- if(reffn == drawrefresh){
- refx = malloc(sizeof(Refx));
- if(refx == 0){
- drawuninstall(client, dstid);
- error(Edrawmem);
- }
- refx->client = client;
- refx->dimage = drawlookup(client, dstid, 1);
- }
- memlsetrefresh(l, reffn, refx);
- }
- continue;
- }
- i = allocmemimage(r, chan);
- if(i == 0)
- error(Edrawmem);
- if(repl)
- i->flags |= Frepl;
- i->clipr = clipr;
- if(!repl)
- rectclip(&i->clipr, r);
- if(drawinstall(client, dstid, i, 0) == 0){
- freememimage(i);
- error(Edrawmem);
- }
- memfillcolor(i, value);
- continue;
-
- /* allocate screen: 'A' id[4] imageid[4] fillid[4] public[1] */
- case 'A':
- printmesg(fmt="LLLb", a, 1);
- m = 1+4+4+4+1;
- if(n < m)
- error(Eshortdraw);
- dstid = BGLONG(a+1);
- if(dstid == 0)
- error(Ebadarg);
- if(drawlookupdscreen(dstid))
- error(Escreenexists);
- ddst = drawlookup(client, BGLONG(a+5), 1);
- dsrc = drawlookup(client, BGLONG(a+9), 1);
- if(ddst==0 || dsrc==0)
- error(Enodrawimage);
- if(drawinstallscreen(client, 0, dstid, ddst, dsrc, a[13]) == 0)
- error(Edrawmem);
- continue;
-
- /* set repl and clip: 'c' dstid[4] repl[1] clipR[4*4] */
- case 'c':
- printmesg(fmt="LbR", a, 0);
- m = 1+4+1+4*4;
- if(n < m)
- error(Eshortdraw);
- ddst = drawlookup(client, BGLONG(a+1), 1);
- if(ddst == nil)
- error(Enodrawimage);
- if(ddst->name)
- error("cannot change repl/clipr of shared image");
- dst = ddst->image;
- if(a[5])
- dst->flags |= Frepl;
- drawrectangle(&dst->clipr, a+6);
- continue;
-
- /* draw: 'd' dstid[4] srcid[4] maskid[4] R[4*4] P[2*4] P[2*4] */
- case 'd':
- printmesg(fmt="LLLRPP", a, 0);
- m = 1+4+4+4+4*4+2*4+2*4;
- if(n < m)
- error(Eshortdraw);
- dst = drawimage(client, a+1);
- dstid = BGLONG(a+1);
- src = drawimage(client, a+5);
- mask = drawimage(client, a+9);
- drawrectangle(&r, a+13);
- drawpoint(&p, a+29);
- drawpoint(&q, a+37);
- op = drawclientop(client);
- memdraw(dst, r, src, p, mask, q, op);
- dstflush(dstid, dst, r);
- continue;
-
- /* toggle debugging: 'D' val[1] */
- case 'D':
- printmesg(fmt="b", a, 0);
- m = 1+1;
- if(n < m)
- error(Eshortdraw);
- continue;
-
- /* ellipse: 'e' dstid[4] srcid[4] center[2*4] a[4] b[4] thick[4] sp[2*4] alpha[4] phi[4]*/
- case 'e':
- case 'E':
- printmesg(fmt="LLPlllPll", a, 0);
- m = 1+4+4+2*4+4+4+4+2*4+2*4;
- if(n < m)
- error(Eshortdraw);
- dst = drawimage(client, a+1);
- dstid = BGLONG(a+1);
- src = drawimage(client, a+5);
- drawpoint(&p, a+9);
- e0 = BGLONG(a+17);
- e1 = BGLONG(a+21);
- if(e0<0 || e1<0)
- error("invalid ellipse semidiameter");
- j = BGLONG(a+25);
- if(j < 0)
- error("negative ellipse thickness");
- drawpoint(&sp, a+29);
- c = j;
- if(*a == 'E')
- c = -1;
- ox = BGLONG(a+37);
- oy = BGLONG(a+41);
- op = drawclientop(client);
- /* high bit indicates arc angles are present */
- if(ox & (1<<31)){
- if((ox & (1<<30)) == 0)
- ox &= ~(1<<31);
- memarc(dst, p, e0, e1, c, src, sp, ox, oy, op);
- }else
- memellipse(dst, p, e0, e1, c, src, sp, op);
- dstflush(dstid, dst, Rect(p.x-e0-j, p.y-e1-j, p.x+e0+j+1, p.y+e1+j+1));
- continue;
-
- /* free: 'f' id[4] */
- case 'f':
- printmesg(fmt="L", a, 1);
- m = 1+4;
- if(n < m)
- error(Eshortdraw);
- ll = drawlookup(client, BGLONG(a+1), 0);
- if(ll && ll->dscreen && ll->dscreen->owner != client)
- ll->dscreen->owner->refreshme = 1;
- drawuninstall(client, BGLONG(a+1));
- continue;
-
- /* free screen: 'F' id[4] */
- case 'F':
- printmesg(fmt="L", a, 1);
- m = 1+4;
- if(n < m)
- error(Eshortdraw);
- drawlookupscreen(client, BGLONG(a+1), &cs);
- drawuninstallscreen(client, cs);
- continue;
-
- /* initialize font: 'i' fontid[4] nchars[4] ascent[1] */
- case 'i':
- printmesg(fmt="Llb", a, 1);
- m = 1+4+4+1;
- if(n < m)
- error(Eshortdraw);
- dstid = BGLONG(a+1);
- if(dstid == 0)
- error("cannot use display as font");
- font = drawlookup(client, dstid, 1);
- if(font == 0)
- error(Enodrawimage);
- if(font->image->layer)
- error("cannot use window as font");
- ni = BGLONG(a+5);
- if(ni<=0 || ni>4096)
- error("bad font size (4096 chars max)");
- free(font->fchar); /* should we complain if non-zero? */
- font->fchar = malloc(ni*sizeof(FChar));
- if(font->fchar == 0)
- error("no memory for font");
- memset(font->fchar, 0, ni*sizeof(FChar));
- font->nfchar = ni;
- font->ascent = a[9];
- continue;
-
- /* load character: 'l' fontid[4] srcid[4] index[2] R[4*4] P[2*4] left[1] width[1] */
- case 'l':
- printmesg(fmt="LLSRPbb", a, 0);
- m = 1+4+4+2+4*4+2*4+1+1;
- if(n < m)
- error(Eshortdraw);
- font = drawlookup(client, BGLONG(a+1), 1);
- if(font == 0)
- error(Enodrawimage);
- if(font->nfchar == 0)
- error(Enotfont);
- src = drawimage(client, a+5);
- ci = BGSHORT(a+9);
- if(ci >= font->nfchar)
- error(Eindex);
- drawrectangle(&r, a+11);
- drawpoint(&p, a+27);
- memdraw(font->image, r, src, p, memopaque, p, S);
- fc = &font->fchar[ci];
- fc->minx = r.min.x;
- fc->maxx = r.max.x;
- fc->miny = r.min.y;
- fc->maxy = r.max.y;
- fc->left = a[35];
- fc->width = a[36];
- continue;
-
- /* draw line: 'L' dstid[4] p0[2*4] p1[2*4] end0[4] end1[4] radius[4] srcid[4] sp[2*4] */
- case 'L':
- printmesg(fmt="LPPlllLP", a, 0);
- m = 1+4+2*4+2*4+4+4+4+4+2*4;
- if(n < m)
- error(Eshortdraw);
- dst = drawimage(client, a+1);
- dstid = BGLONG(a+1);
- drawpoint(&p, a+5);
- drawpoint(&q, a+13);
- e0 = BGLONG(a+21);
- e1 = BGLONG(a+25);
- j = BGLONG(a+29);
- if(j < 0)
- error("negative line width");
- src = drawimage(client, a+33);
- drawpoint(&sp, a+37);
- op = drawclientop(client);
- memline(dst, p, q, e0, e1, j, src, sp, op);
- /* avoid memlinebbox if possible */
- if(dstid==0 || dst->layer!=nil){
- /* BUG: this is terribly inefficient: update maximal containing rect*/
- r = memlinebbox(p, q, e0, e1, j);
- dstflush(dstid, dst, insetrect(r, -(1+1+j)));
- }
- continue;
-
- /* create image mask: 'm' newid[4] id[4] */
-/*
- *
- case 'm':
- printmesg("LL", a, 0);
- m = 4+4;
- if(n < m)
- error(Eshortdraw);
- break;
- *
- */
-
- /* attach to a named image: 'n' dstid[4] j[1] name[j] */
- case 'n':
- printmesg(fmt="Lz", a, 0);
- m = 1+4+1;
- if(n < m)
- error(Eshortdraw);
- j = a[5];
- if(j == 0) /* give me a non-empty name please */
- error(Eshortdraw);
- m += j;
- if(n < m)
- error(Eshortdraw);
- dstid = BGLONG(a+1);
- if(drawlookup(client, dstid, 0))
- error(Eimageexists);
- dn = drawlookupname(j, (char*)a+6);
- if(dn == nil)
- error(Enoname);
- if(drawinstall(client, dstid, dn->dimage->image, 0) == 0)
- error(Edrawmem);
- di = drawlookup(client, dstid, 0);
- if(di == 0)
- error("draw: cannot happen");
- di->vers = dn->vers;
- di->name = smalloc(j+1);
- di->fromname = dn->dimage;
- di->fromname->ref++;
- memmove(di->name, a+6, j);
- di->name[j] = 0;
- client->infoid = dstid;
- continue;
-
- /* name an image: 'N' dstid[4] in[1] j[1] name[j] */
- case 'N':
- printmesg(fmt="Lbz", a, 0);
- m = 1+4+1+1;
- if(n < m)
- error(Eshortdraw);
- c = a[5];
- j = a[6];
- if(j == 0) /* give me a non-empty name please */
- error(Eshortdraw);
- m += j;
- if(n < m)
- error(Eshortdraw);
- di = drawlookup(client, BGLONG(a+1), 0);
- if(di == 0)
- error(Enodrawimage);
- if(di->name)
- error(Enamed);
- if(c)
- drawaddname(client, di, j, (char*)a+7);
- else{
- dn = drawlookupname(j, (char*)a+7);
- if(dn == nil)
- error(Enoname);
- if(dn->dimage != di)
- error(Ewrongname);
- drawdelname(dn);
- }
- continue;
-
- /* position window: 'o' id[4] r.min [2*4] screenr.min [2*4] */
- case 'o':
- printmesg(fmt="LPP", a, 0);
- m = 1+4+2*4+2*4;
- if(n < m)
- error(Eshortdraw);
- dst = drawimage(client, a+1);
- if(dst->layer){
- drawpoint(&p, a+5);
- drawpoint(&q, a+13);
- r = dst->layer->screenr;
- ni = memlorigin(dst, p, q);
- if(ni < 0)
- error("image origin failed");
- if(ni > 0){
- addflush(r);
- addflush(dst->layer->screenr);
- ll = drawlookup(client, BGLONG(a+1), 1);
- drawrefreshscreen(ll, client);
- }
- }
- continue;
-
- /* set compositing operator for next draw operation: 'O' op */
- case 'O':
- printmesg(fmt="b", a, 0);
- m = 1+1;
- if(n < m)
- error(Eshortdraw);
- client->op = a[1];
- continue;
-
- /* filled polygon: 'P' dstid[4] n[2] wind[4] ignore[2*4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
- /* polygon: 'p' dstid[4] n[2] end0[4] end1[4] radius[4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
- case 'p':
- case 'P':
- printmesg(fmt="LslllLPP", a, 0);
- m = 1+4+2+4+4+4+4+2*4;
- if(n < m)
- error(Eshortdraw);
- dstid = BGLONG(a+1);
- dst = drawimage(client, a+1);
- ni = BGSHORT(a+5);
- if(ni < 0)
- error("negative count in polygon");
- e0 = BGLONG(a+7);
- e1 = BGLONG(a+11);
- j = 0;
- if(*a == 'p'){
- j = BGLONG(a+15);
- if(j < 0)
- error("negative polygon line width");
- }
- src = drawimage(client, a+19);
- drawpoint(&sp, a+23);
- drawpoint(&p, a+31);
- ni++;
- pp = malloc(ni*sizeof(Point));
- if(pp == nil)
- error(Enomem);
- doflush = 0;
- if(dstid==0 || (screenimage && dst->layer && dst->layer->screen->image->data == screenimage->data))
- doflush = 1; /* simplify test in loop */
- ox = oy = 0;
- esize = 0;
- u = a+m;
- for(y=0; y<ni; y++){
- q = p;
- oesize = esize;
- u = drawcoord(u, a+n, ox, &p.x);
- u = drawcoord(u, a+n, oy, &p.y);
- ox = p.x;
- oy = p.y;
- if(doflush){
- esize = j;
- if(*a == 'p'){
- if(y == 0){
- c = memlineendsize(e0);
- if(c > esize)
- esize = c;
- }
- if(y == ni-1){
- c = memlineendsize(e1);
- if(c > esize)
- esize = c;
- }
- }
- if(*a=='P' && e0!=1 && e0 !=~0)
- r = dst->clipr;
- else if(y > 0){
- r = Rect(q.x-oesize, q.y-oesize, q.x+oesize+1, q.y+oesize+1);
- combinerect(&r, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1));
- }
- if(rectclip(&r, dst->clipr)) /* should perhaps be an arg to dstflush */
- dstflush(dstid, dst, r);
- }
- pp[y] = p;
- }
- if(y == 1)
- dstflush(dstid, dst, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1));
- op = drawclientop(client);
- if(*a == 'p')
- mempoly(dst, pp, ni, e0, e1, j, src, sp, op);
- else
- memfillpoly(dst, pp, ni, e0, src, sp, op);
- free(pp);
- m = u-a;
- continue;
-
- /* read: 'r' id[4] R[4*4] */
- case 'r':
- printmesg(fmt="LR", a, 0);
- m = 1+4+4*4;
- if(n < m)
- error(Eshortdraw);
- i = drawimage(client, a+1);
- drawrectangle(&r, a+5);
- if(!rectinrect(r, i->r))
- error(Ereadoutside);
- c = bytesperline(r, i->depth);
- c *= Dy(r);
- free(client->readdata);
- client->readdata = mallocz(c, 0);
- if(client->readdata == nil)
- error("readimage malloc failed");
- client->nreaddata = memunload(i, r, client->readdata, c);
- if(client->nreaddata < 0){
- free(client->readdata);
- client->readdata = nil;
- error("bad readimage call");
- }
- continue;
-
- /* string: 's' dstid[4] srcid[4] fontid[4] P[2*4] clipr[4*4] sp[2*4] ni[2] ni*(index[2]) */
- /* stringbg: 'x' dstid[4] srcid[4] fontid[4] P[2*4] clipr[4*4] sp[2*4] ni[2] bgid[4] bgpt[2*4] ni*(index[2]) */
- case 's':
- case 'x':
- printmesg(fmt="LLLPRPs", a, 0);
- m = 1+4+4+4+2*4+4*4+2*4+2;
- if(*a == 'x')
- m += 4+2*4;
- if(n < m)
- error(Eshortdraw);
-
- dst = drawimage(client, a+1);
- dstid = BGLONG(a+1);
- src = drawimage(client, a+5);
- font = drawlookup(client, BGLONG(a+9), 1);
- if(font == 0)
- error(Enodrawimage);
- if(font->nfchar == 0)
- error(Enotfont);
- drawpoint(&p, a+13);
- drawrectangle(&r, a+21);
- drawpoint(&sp, a+37);
- ni = BGSHORT(a+45);
- u = a+m;
- m += ni*2;
- if(n < m)
- error(Eshortdraw);
- clipr = dst->clipr;
- dst->clipr = r;
- op = drawclientop(client);
- bg = dst;
- if(*a == 'x'){
- /* paint background */
- bg = drawimage(client, a+47);
- drawpoint(&q, a+51);
- r.min.x = p.x;
- r.min.y = p.y-font->ascent;
- r.max.x = p.x;
- r.max.y = r.min.y+Dy(font->image->r);
- j = ni;
- while(--j >= 0){
- ci = BGSHORT(u);
- if(ci<0 || ci>=font->nfchar){
- dst->clipr = clipr;
- error(Eindex);
- }
- r.max.x += font->fchar[ci].width;
- u += 2;
- }
- memdraw(dst, r, bg, q, memopaque, ZP, op);
- u -= 2*ni;
- }
- q = p;
- while(--ni >= 0){
- ci = BGSHORT(u);
- if(ci<0 || ci>=font->nfchar){
- dst->clipr = clipr;
- error(Eindex);
- }
- q = drawchar(dst, bg, q, src, &sp, font, ci, op);
- u += 2;
- }
- dst->clipr = clipr;
- p.y -= font->ascent;
- dstflush(dstid, dst, Rect(p.x, p.y, q.x, p.y+Dy(font->image->r)));
- continue;
-
- /* use public screen: 'S' id[4] chan[4] */
- case 'S':
- printmesg(fmt="Ll", a, 0);
- m = 1+4+4;
- if(n < m)
- error(Eshortdraw);
- dstid = BGLONG(a+1);
- if(dstid == 0)
- error(Ebadarg);
- dscrn = drawlookupdscreen(dstid);
- if(dscrn==0 || (dscrn->public==0 && dscrn->owner!=client))
- error(Enodrawscreen);
- if(dscrn->screen->image->chan != BGLONG(a+5))
- error("inconsistent chan");
- if(drawinstallscreen(client, dscrn, 0, 0, 0, 0) == 0)
- error(Edrawmem);
- continue;
-
- /* top or bottom windows: 't' top[1] nw[2] n*id[4] */
- case 't':
- printmesg(fmt="bsL", a, 0);
- m = 1+1+2;
- if(n < m)
- error(Eshortdraw);
- nw = BGSHORT(a+2);
- if(nw < 0)
- error(Ebadarg);
- if(nw == 0)
- continue;
- m += nw*4;
- if(n < m)
- error(Eshortdraw);
- lp = malloc(nw*sizeof(Memimage*));
- if(lp == 0)
- error(Enomem);
- if(waserror()){
- free(lp);
- nexterror();
- }
- for(j=0; j<nw; j++){
- lp[j] = drawimage(client, a+1+1+2+j*4);
- if(lp[j]->layer == 0)
- error("images are not windows");
- if(lp[j]->layer->screen != lp[0]->layer->screen)
- error("images not on same screen");
- }
- if(a[1])
- memltofrontn(lp, nw);
- else
- memltorearn(lp, nw);
- if(screenimage && lp[0]->layer->screen->image->data == screenimage->data)
- for(j=0; j<nw; j++)
- addflush(lp[j]->layer->screenr);
- ll = drawlookup(client, BGLONG(a+1+1+2), 1);
- drawrefreshscreen(ll, client);
- poperror();
- free(lp);
- continue;
-
- /* visible: 'v' */
- case 'v':
- printmesg(fmt="", a, 0);
- m = 1;
- drawflush();
- continue;
-
- /* write: 'y' id[4] R[4*4] data[x*1] */
- /* write from compressed data: 'Y' id[4] R[4*4] data[x*1] */
- case 'y':
- case 'Y':
- printmesg(fmt="LR", a, 0);
- // iprint("load %c\n", *a);
- m = 1+4+4*4;
- if(n < m)
- error(Eshortdraw);
- dstid = BGLONG(a+1);
- dst = drawimage(client, a+1);
- drawrectangle(&r, a+5);
- if(!rectinrect(r, dst->r))
- error(Ewriteoutside);
- y = memload(dst, r, a+m, n-m, *a=='Y');
- if(y < 0)
- error("bad writeimage call");
- dstflush(dstid, dst, r);
- m += y;
- continue;
- }
- }
- poperror();
-}
-
-Dev drawdevtab = {
- 'i',
- "draw",
-
- devreset,
- devinit,
- devshutdown,
- drawattach,
- drawwalk,
- drawstat,
- drawopen,
- devcreate,
- drawclose,
- drawread,
- devbread,
- drawwrite,
- devbwrite,
- devremove,
- devwstat,
-};
-
-/*
- * On 8 bit displays, load the default color map
- */
-void
-drawcmap(void)
-{
- int r, g, b, cr, cg, cb, v;
- int num, den;
- int i, j;
-
- for(r=0,i=0; r!=4; r++)
- for(v=0; v!=4; v++,i+=16){
- for(g=0,j=v-r; g!=4; g++)
- for(b=0;b!=4;b++,j++){
- den = r;
- if(g > den)
- den = g;
- if(b > den)
- den = b;
- if(den == 0) /* divide check -- pick grey shades */
- cr = cg = cb = v*17;
- else{
- num = 17*(4*den+v);
- cr = r*num/den;
- cg = g*num/den;
- cb = b*num/den;
- }
- setcolor(i+(j&15),
- cr*0x01010101, cg*0x01010101, cb*0x01010101);
- }
- }
-}
--- a/kern/devfs-win32.c
+++ b/kern/devfs-win32.c
@@ -9,7 +9,8 @@
#include "fns.h"
#include "error.h"
-#include <libsec.h> /* for sha1 in pathhash() */
+// TODO: get sha1 without pulling in libsec
+//#include <libsec.h> /* for sha1 in pathhash() */
typedef struct DIR DIR;
typedef struct Ufsinfo Ufsinfo;
--- a/kern/devip-posix.c
+++ /dev/null
@@ -1,259 +1,0 @@
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-#include "ip.h"
-
-#include "devip.h"
-
-#undef listen
-#undef accept
-#undef bind
-
-static int
-family(unsigned char *addr)
-{
- if(isv4(addr))
- return AF_INET;
- return AF_INET6;
-}
-
-static int
-addrlen(struct sockaddr_storage *ss)
-{
- switch(ss->ss_family){
- case AF_INET:
- return sizeof(struct sockaddr_in);
- case AF_INET6:
- return sizeof(struct sockaddr_in6);
- }
- return 0;
-}
-
-void
-osipinit(void)
-{
- char buf[1024];
- gethostname(buf, sizeof(buf));
- kstrdup(&sysname, buf);
-
-}
-
-int
-so_socket(int type, unsigned char *addr)
-{
- int fd, one;
-
- switch(type) {
- default:
- error("bad protocol type");
- case S_TCP:
- type = SOCK_STREAM;
- break;
- case S_UDP:
- type = SOCK_DGRAM;
- break;
- }
-
- fd = socket(family(addr), type, 0);
- if(fd < 0)
- oserror();
-
- one = 1;
- if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(one)) > 0){
- oserrstr();
- print("setsockopt: %r");
- }
-
- return fd;
-}
-
-void
-so_connect(int fd, unsigned char *raddr, unsigned short rport)
-{
- struct sockaddr_storage ss;
-
- memset(&ss, 0, sizeof(ss));
-
- ss.ss_family = family(raddr);
-
- switch(ss.ss_family){
- case AF_INET:
- hnputs(&((struct sockaddr_in*)&ss)->sin_port, rport);
- v6tov4((unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr, raddr);
- break;
- case AF_INET6:
- hnputs(&((struct sockaddr_in6*)&ss)->sin6_port, rport);
- memcpy(&((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, raddr, sizeof(struct in6_addr));
- break;
- }
-
- if(connect(fd, (struct sockaddr*)&ss, addrlen(&ss)) < 0)
- oserror();
-}
-
-void
-so_getsockname(int fd, unsigned char *laddr, unsigned short *lport)
-{
- socklen_t len;
- struct sockaddr_storage ss;
-
- len = sizeof(ss);
- if(getsockname(fd, (struct sockaddr*)&ss, &len) < 0)
- oserror();
-
- switch(ss.ss_family){
- case AF_INET:
- v4tov6(laddr, (unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr);
- *lport = nhgets(&((struct sockaddr_in*)&ss)->sin_port);
- break;
- case AF_INET6:
- memcpy(laddr, &((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, sizeof(struct in6_addr));
- *lport = nhgets(&((struct sockaddr_in6*)&ss)->sin6_port);
- break;
- default:
- error("not AF_INET or AF_INET6");
- }
-}
-
-void
-so_listen(int fd)
-{
- if(listen(fd, 5) < 0)
- oserror();
-}
-
-int
-so_accept(int fd, unsigned char *raddr, unsigned short *rport)
-{
- int nfd;
- socklen_t len;
- struct sockaddr_storage ss;
-
- len = sizeof(ss);
- nfd = accept(fd, (struct sockaddr*)&ss, &len);
- if(nfd < 0)
- oserror();
-
- switch(ss.ss_family){
- case AF_INET:
- v4tov6(raddr, (unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr);
- *rport = nhgets(&((struct sockaddr_in*)&ss)->sin_port);
- break;
- case AF_INET6:
- memcpy(raddr, &((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, sizeof(struct in6_addr));
- *rport = nhgets(&((struct sockaddr_in6*)&ss)->sin6_port);
- break;
- default:
- error("not AF_INET or AF_INET6");
- }
- return nfd;
-}
-
-void
-so_bind(int fd, int su, unsigned short port, unsigned char *addr)
-{
- int i, one;
- struct sockaddr_storage ss;
-
- one = 1;
- if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one)) < 0){
- oserrstr();
- print("setsockopt: %r");
- }
-
- if(su) {
- for(i = 600; i < 1024; i++) {
- memset(&ss, 0, sizeof(ss));
- ss.ss_family = family(addr);
-
- switch(ss.ss_family){
- case AF_INET:
- ((struct sockaddr_in*)&ss)->sin_port = i;
- break;
- case AF_INET6:
- ((struct sockaddr_in6*)&ss)->sin6_port = i;
- break;
- }
-
- if(bind(fd, (struct sockaddr*)&ss, addrlen(&ss)) >= 0)
- return;
- }
- oserror();
- }
-
- memset(&ss, 0, sizeof(ss));
- ss.ss_family = family(addr);
-
- switch(ss.ss_family){
- case AF_INET:
- hnputs(&((struct sockaddr_in*)&ss)->sin_port, port);
- break;
- case AF_INET6:
- hnputs(&((struct sockaddr_in6*)&ss)->sin6_port, port);
- break;
- }
-
- if(bind(fd, (struct sockaddr*)&ss, addrlen(&ss)) < 0)
- oserror();
-}
-
-int
-so_gethostbyname(char *host, char **hostv, int n)
-{
- char buf[INET6_ADDRSTRLEN];
- struct addrinfo *r, *p;
- int i;
-
- r = NULL;
- if(getaddrinfo(host, NULL, NULL, &r))
- return 0;
- for(i = 0, p = r; i < n && p != NULL; p = p->ai_next){
- switch (p->ai_family) {
- default:
- continue;
- case AF_INET:
- inet_ntop(AF_INET, &((struct sockaddr_in*)p->ai_addr)->sin_addr, buf, sizeof(buf));
- break;
- case AF_INET6:
- inet_ntop(AF_INET6, &((struct sockaddr_in6*)p->ai_addr)->sin6_addr, buf, sizeof(buf));
- break;
- }
- hostv[i++] = strdup(buf);
- }
- freeaddrinfo(r);
- return i;
-}
-
-int
-so_getservbyname(char *service, char *net, char *port)
-{
- struct servent *s;
-
- s = getservbyname(service, net);
- if(s == 0)
- return -1;
-
- sprint(port, "%d", nhgets(&s->s_port));
- return 0;
-}
-
-int
-so_send(int fd, void *d, int n, int f)
-{
- return send(fd, d, n, f);
-}
-
-int
-so_recv(int fd, void *d, int n, int f)
-{
- return recv(fd, d, n, f);
-}
--- a/kern/devip-win32.c
+++ /dev/null
@@ -1,265 +1,0 @@
-#define _WIN32_WINNT 0x0501
-#include <winsock2.h>
-#include <windows.h>
-#include <ws2tcpip.h>
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-#include "ip.h"
-
-#include "devip.h"
-
-#ifdef MSVC
-#pragma comment(lib, "wsock32.lib")
-#endif
-
-#undef listen
-#undef accept
-#undef bind
-
-static int
-family(unsigned char *addr)
-{
- if(isv4(addr))
- return AF_INET;
- return AF_INET6;
-}
-
-static int
-addrlen(struct sockaddr_storage *ss)
-{
- switch(ss->ss_family){
- case AF_INET:
- return sizeof(struct sockaddr_in);
- case AF_INET6:
- return sizeof(struct sockaddr_in6);
- }
- return 0;
-}
-
-void
-osipinit(void)
-{
- WSADATA wasdat;
- char buf[1024];
-
- if(WSAStartup(MAKEWORD(1, 1), &wasdat) != 0)
- panic("no winsock.dll");
-
- gethostname(buf, sizeof(buf));
- kstrdup(&sysname, buf);
-}
-
-int
-so_socket(int type, unsigned char *addr)
-{
- int fd, one;
-
- switch(type) {
- default:
- error("bad protocol type");
- case S_TCP:
- type = SOCK_STREAM;
- break;
- case S_UDP:
- type = SOCK_DGRAM;
- break;
- }
-
- fd = socket(family(addr), type, 0);
- if(fd < 0)
- oserror();
-
- one = 1;
- if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(one)) > 0){
- oserrstr();
- print("setsockopt: %s\n", up->errstr);
- }
-
- return fd;
-}
-
-
-void
-so_connect(int fd, unsigned char *raddr, unsigned short rport)
-{
- struct sockaddr_storage ss;
-
- memset(&ss, 0, sizeof(ss));
-
- ss.ss_family = family(raddr);
-
- switch(ss.ss_family){
- case AF_INET:
- hnputs(&((struct sockaddr_in*)&ss)->sin_port, rport);
- v6tov4((unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr, raddr);
- break;
- case AF_INET6:
- hnputs(&((struct sockaddr_in6*)&ss)->sin6_port, rport);
- memcpy(&((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, raddr, sizeof(struct in6_addr));
- break;
- }
-
- if(connect(fd, (struct sockaddr*)&ss, addrlen(&ss)) < 0)
- oserror();
-}
-
-void
-so_getsockname(int fd, unsigned char *laddr, unsigned short *lport)
-{
- int len;
- struct sockaddr_storage ss;
-
- len = sizeof(ss);
- if(getsockname(fd, (struct sockaddr*)&ss, &len) < 0)
- oserror();
-
- switch(ss.ss_family){
- case AF_INET:
- v4tov6(laddr, (unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr);
- *lport = nhgets(&((struct sockaddr_in*)&ss)->sin_port);
- break;
- case AF_INET6:
- memcpy(laddr, &((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, sizeof(struct in6_addr));
- *lport = nhgets(&((struct sockaddr_in6*)&ss)->sin6_port);
- break;
- default:
- error("not AF_INET or AF_INET6");
- }
-}
-
-void
-so_listen(int fd)
-{
- if(listen(fd, 5) < 0)
- oserror();
-}
-
-int
-so_accept(int fd, unsigned char *raddr, unsigned short *rport)
-{
- int nfd;
- int len;
- struct sockaddr_storage ss;
-
- len = sizeof(ss);
- nfd = accept(fd, (struct sockaddr*)&ss, &len);
- if(nfd < 0)
- oserror();
-
- switch(ss.ss_family){
- case AF_INET:
- v4tov6(raddr, (unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr);
- *rport = nhgets(&((struct sockaddr_in*)&ss)->sin_port);
- break;
- case AF_INET6:
- memcpy(raddr, &((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, sizeof(struct in6_addr));
- *rport = nhgets(&((struct sockaddr_in6*)&ss)->sin6_port);
- break;
- default:
- error("not AF_INET or AF_INET6");
- }
- return nfd;
-}
-
-void
-so_bind(int fd, int su, unsigned short port, unsigned char *addr)
-{
- int i, one;
- struct sockaddr_storage ss;
-
- one = 1;
- if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one)) < 0){
- oserrstr();
- print("setsockopt: %r");
- }
-
- if(su) {
- for(i = 600; i < 1024; i++) {
- memset(&ss, 0, sizeof(ss));
- ss.ss_family = family(addr);
-
- switch(ss.ss_family){
- case AF_INET:
- ((struct sockaddr_in*)&ss)->sin_port = i;
- break;
- case AF_INET6:
- ((struct sockaddr_in6*)&ss)->sin6_port = i;
- break;
- }
-
- if(bind(fd, (struct sockaddr*)&ss, addrlen(&ss)) >= 0)
- return;
- }
- oserror();
- }
-
- memset(&ss, 0, sizeof(ss));
- ss.ss_family = family(addr);
-
- switch(ss.ss_family){
- case AF_INET:
- hnputs(&((struct sockaddr_in*)&ss)->sin_port, port);
- break;
- case AF_INET6:
- hnputs(&((struct sockaddr_in6*)&ss)->sin6_port, port);
- break;
- }
-
- if(bind(fd, (struct sockaddr*)&ss, addrlen(&ss)) < 0)
- oserror();
-}
-
-int
-so_gethostbyname(char *host, char **hostv, int n)
-{
- char buf[INET6_ADDRSTRLEN];
- struct addrinfo *r, *p;
- DWORD l;
- int i;
-
- r = NULL;
- if(getaddrinfo(host, NULL, NULL, &r))
- return 0;
- for(i = 0, p = r; i < n && p != NULL; p = p->ai_next){
- switch (p->ai_family) {
- default:
- continue;
- case AF_INET:
- case AF_INET6:
- l = sizeof(buf);
- WSAAddressToStringA(p->ai_addr, p->ai_addrlen, NULL, buf, &l);
- break;
- }
- hostv[i++] = strdup(buf);
- }
- freeaddrinfo(r);
- return i;
-}
-
-int
-so_getservbyname(char *service, char *net, char *port)
-{
- struct servent *s;
-
- s = getservbyname(service, net);
- if(s == 0)
- return -1;
-
- sprint(port, "%d", nhgets(&s->s_port));
- return 0;
-}
-
-int
-so_send(int fd, void *d, int n, int f)
-{
- return send(fd, d, n, f);
-}
-
-int
-so_recv(int fd, void *d, int n, int f)
-{
- return recv(fd, d, n, f);
-}
--- a/kern/devip.c
+++ /dev/null
@@ -1,870 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-#include "ip.h"
-
-#include "devip.h"
-
-void csclose(Chan*);
-long csread(Chan*, void*, long, vlong);
-long cswrite(Chan*, void*, long, vlong);
-
-void osipinit(void);
-
-enum
-{
- Qtopdir = 1, /* top level directory */
- Qtopbase,
- Qcs = Qtopbase,
-
- Qprotodir, /* directory for a protocol */
- Qprotobase,
- Qclone = Qprotobase,
-
- Qconvdir, /* directory for a conversation */
- Qconvbase,
- Qctl = Qconvbase,
- Qdata,
- Qstatus,
- Qremote,
- Qlocal,
- Qlisten,
-
- MAXPROTO = 4
-};
-#define TYPE(x) ((int)((x).path & 0xf))
-#define CONV(x) ((int)(((x).path >> 4)&0xfff))
-#define PROTO(x) ((int)(((x).path >> 16)&0xff))
-#define QID(p, c, y) (((p)<<16) | ((c)<<4) | (y))
-#define ipzero(x) memset(x, 0, IPaddrlen)
-
-typedef struct Proto Proto;
-typedef struct Conv Conv;
-struct Conv
-{
- int x;
- Ref r;
- int sfd;
- int perm;
- char owner[KNAMELEN];
- char* state;
- uchar laddr[IPaddrlen];
- ushort lport;
- uchar raddr[IPaddrlen];
- ushort rport;
- int restricted;
- char cerr[KNAMELEN];
- Proto* p;
-};
-
-struct Proto
-{
- Lock l;
- int x;
- int stype;
- char name[KNAMELEN];
- int nc;
- int maxconv;
- Conv** conv;
- Qid qid;
-};
-
-static int np;
-static Proto proto[MAXPROTO];
-
-static Conv* protoclone(Proto*, char*, int);
-static void setladdr(Conv*);
-
-static char network[] = "network";
-
-static int
-ip3gen(Chan *c, int i, Dir *dp)
-{
- Qid q;
- Conv *cv;
- char *p;
-
- cv = proto[PROTO(c->qid)].conv[CONV(c->qid)];
- mkqid(&q, QID(PROTO(c->qid), CONV(c->qid), i), 0, QTFILE);
-
- switch(i) {
- default:
- return -1;
- case Qctl:
- devdir(c, q, "ctl", 0, cv->owner, cv->perm, dp);
- return 1;
- case Qdata:
- devdir(c, q, "data", 0, cv->owner, cv->perm, dp);
- return 1;
- case Qlisten:
- devdir(c, q, "listen", 0, cv->owner, cv->perm, dp);
- return 1;
- case Qlocal:
- p = "local";
- break;
- case Qremote:
- p = "remote";
- break;
- case Qstatus:
- p = "status";
- break;
- }
- devdir(c, q, p, 0, cv->owner, 0444, dp);
- return 1;
-}
-
-static int
-ip2gen(Chan *c, int i, Dir *dp)
-{
- Qid q;
-
- switch(i) {
- case Qclone:
- mkqid(&q, QID(PROTO(c->qid), 0, Qclone), 0, QTFILE);
- devdir(c, q, "clone", 0, network, 0666, dp);
- return 1;
- }
- return -1;
-}
-
-static int
-ip1gen(Chan *c, int i, Dir *dp)
-{
- Qid q;
- char *p;
- int prot;
- int len = 0;
-
- prot = 0666;
- mkqid(&q, QID(0, 0, i), 0, QTFILE);
- switch(i) {
- default:
- return -1;
- case Qcs:
- p = "cs";
- prot = 0664;
- break;
- }
- devdir(c, q, p, len, network, prot, dp);
- return 1;
-}
-
-static int
-ipgen(Chan *c, char *nname, Dirtab *d, int nd, int s, Dir *dp)
-{
- Qid q;
- Conv *cv;
-
- switch(TYPE(c->qid)) {
- case Qtopdir:
- if(s == DEVDOTDOT){
- mkqid(&q, QID(0, 0, Qtopdir), 0, QTDIR);
- snprint(up->genbuf, sizeof up->genbuf, "#I%lud", c->dev);
- devdir(c, q, up->genbuf, 0, network, 0555, dp);
- return 1;
- }
- if(s < np) {
- mkqid(&q, QID(s, 0, Qprotodir), 0, QTDIR);
- devdir(c, q, proto[s].name, 0, network, 0555, dp);
- return 1;
- }
- s -= np;
- return ip1gen(c, s+Qtopbase, dp);
- case Qcs:
- return ip1gen(c, TYPE(c->qid), dp);
- case Qprotodir:
- if(s == DEVDOTDOT){
- mkqid(&q, QID(0, 0, Qtopdir), 0, QTDIR);
- snprint(up->genbuf, sizeof up->genbuf, "#I%lud", c->dev);
- devdir(c, q, up->genbuf, 0, network, 0555, dp);
- return 1;
- }
- if(s < proto[PROTO(c->qid)].nc) {
- cv = proto[PROTO(c->qid)].conv[s];
- snprint(up->genbuf, sizeof up->genbuf, "%d", s);
- mkqid(&q, QID(PROTO(c->qid), s, Qconvdir), 0, QTDIR);
- devdir(c, q, up->genbuf, 0, cv->owner, 0555, dp);
- return 1;
- }
- s -= proto[PROTO(c->qid)].nc;
- return ip2gen(c, s+Qprotobase, dp);
- case Qclone:
- return ip2gen(c, TYPE(c->qid), dp);
- case Qconvdir:
- if(s == DEVDOTDOT){
- s = PROTO(c->qid);
- mkqid(&q, QID(s, 0, Qprotodir), 0, QTDIR);
- devdir(c, q, proto[s].name, 0, network, 0555, dp);
- return 1;
- }
- return ip3gen(c, s+Qconvbase, dp);
- case Qctl:
- case Qdata:
- case Qlisten:
- case Qlocal:
- case Qremote:
- case Qstatus:
- return ip3gen(c, TYPE(c->qid), dp);
- }
- return -1;
-}
-
-static void
-newproto(char *name, int type, int maxconv)
-{
- int l;
- Proto *p;
-
- if(np >= MAXPROTO) {
- print("no %s: increase MAXPROTO", name);
- return;
- }
-
- p = &proto[np];
- strcpy(p->name, name);
- p->stype = type;
- p->qid.path = QID(np, 0, Qprotodir);
- p->qid.type = QTDIR;
- p->x = np++;
- p->maxconv = maxconv;
- l = sizeof(Conv*)*(p->maxconv+1);
- p->conv = mallocz(l, 1);
- if(p->conv == 0)
- panic("no memory");
-}
-
-void
-ipinit(void)
-{
- osipinit();
-
- newproto("udp", S_UDP, 10);
- newproto("tcp", S_TCP, 30);
-
- fmtinstall('I', eipfmt);
- fmtinstall('E', eipfmt);
-
-}
-
-Chan *
-ipattach(char *spec)
-{
- Chan *c;
-
- c = devattach('I', spec);
- c->qid.path = QID(0, 0, Qtopdir);
- c->qid.type = QTDIR;
- c->qid.vers = 0;
- return c;
-}
-
-static Walkqid*
-ipwalk(Chan *c, Chan *nc, char **name, int nname)
-{
- return devwalk(c, nc, name, nname, 0, 0, ipgen);
-}
-
-int
-ipstat(Chan *c, uchar *dp, int n)
-{
- return devstat(c, dp, n, 0, 0, ipgen);
-}
-
-Chan *
-ipopen(Chan *c, int omode)
-{
- Proto *p;
- uchar raddr[IPaddrlen];
- ushort rport;
- int perm, sfd;
- Conv *cv, *lcv;
-
- omode &= 3;
- perm = 0;
- switch(omode) {
- case OREAD:
- perm = 4;
- break;
- case OWRITE:
- perm = 2;
- break;
- case ORDWR:
- perm = 6;
- break;
- }
-
- switch(TYPE(c->qid)) {
- default:
- break;
- case Qtopdir:
- case Qprotodir:
- case Qconvdir:
- case Qstatus:
- case Qremote:
- case Qlocal:
- if(omode != OREAD)
- error(Eperm);
- break;
- case Qclone:
- p = &proto[PROTO(c->qid)];
- cv = protoclone(p, up->user, -1);
- if(cv == 0)
- error(Enodev);
- c->qid.path = QID(p->x, cv->x, Qctl);
- c->qid.vers = 0;
- break;
- case Qdata:
- case Qctl:
- p = &proto[PROTO(c->qid)];
- lock(&p->l);
- cv = p->conv[CONV(c->qid)];
- lock(&cv->r.lk);
- if((perm & (cv->perm>>6)) != perm) {
- if(strcmp(up->user, cv->owner) != 0 ||
- (perm & cv->perm) != perm) {
- unlock(&cv->r.lk);
- unlock(&p->l);
- error(Eperm);
- }
- }
- cv->r.ref++;
- if(cv->r.ref == 1) {
- memmove(cv->owner, up->user, KNAMELEN);
- cv->perm = 0660;
- }
- unlock(&cv->r.lk);
- unlock(&p->l);
- break;
- case Qlisten:
- p = &proto[PROTO(c->qid)];
- lcv = p->conv[CONV(c->qid)];
- sfd = so_accept(lcv->sfd, raddr, &rport);
- cv = protoclone(p, up->user, sfd);
- if(cv == 0) {
- close(sfd);
- error(Enodev);
- }
- ipmove(cv->raddr, raddr);
- cv->rport = rport;
- setladdr(cv);
- cv->state = "Established";
- c->qid.path = QID(p->x, cv->x, Qctl);
- break;
- }
- c->mode = openmode(omode);
- c->flag |= COPEN;
- c->offset = 0;
- return c;
-}
-
-void
-ipclose(Chan *c)
-{
- Conv *cc;
-
- switch(TYPE(c->qid)) {
- case Qcs:
- csclose(c);
- break;
- case Qdata:
- case Qctl:
- if((c->flag & COPEN) == 0)
- break;
- cc = proto[PROTO(c->qid)].conv[CONV(c->qid)];
- if(decref(&cc->r) != 0)
- break;
- strcpy(cc->owner, network);
- cc->perm = 0666;
- cc->state = "Closed";
- ipzero(cc->laddr);
- ipzero(cc->raddr);
- cc->lport = 0;
- cc->rport = 0;
- close(cc->sfd);
- break;
- }
-}
-
-long
-ipread(Chan *ch, void *a, long n, vlong offset)
-{
- int r;
- Conv *c;
- Proto *x;
- uchar ip[IPaddrlen];
- char buf[128], *p;
-
-/*print("ipread %s %lux\n", chanpath(ch), (long)ch->qid.path);*/
- p = a;
- switch(TYPE(ch->qid)) {
- default:
- error(Eperm);
- case Qcs:
- return csread(ch, a, n, offset);
- case Qprotodir:
- case Qtopdir:
- case Qconvdir:
- return devdirread(ch, a, n, 0, 0, ipgen);
- case Qctl:
- sprint(buf, "%d", CONV(ch->qid));
- return readstr(offset, p, n, buf);
- case Qremote:
- c = proto[PROTO(ch->qid)].conv[CONV(ch->qid)];
- ipmove(ip, c->raddr);
- sprint(buf, "%I!%d\n", ip, c->rport);
- return readstr(offset, p, n, buf);
- case Qlocal:
- c = proto[PROTO(ch->qid)].conv[CONV(ch->qid)];
- ipmove(ip, c->laddr);
- sprint(buf, "%I!%d\n", ip, c->lport);
- return readstr(offset, p, n, buf);
- case Qstatus:
- x = &proto[PROTO(ch->qid)];
- c = x->conv[CONV(ch->qid)];
- sprint(buf, "%s/%d %d %s \n",
- c->p->name, c->x, c->r.ref, c->state);
- return readstr(offset, p, n, buf);
- case Qdata:
- c = proto[PROTO(ch->qid)].conv[CONV(ch->qid)];
- r = so_recv(c->sfd, a, n, 0);
- if(r < 0){
- oserrstr();
- nexterror();
- }
- return r;
- }
-}
-
-static void
-setladdr(Conv *c)
-{
- so_getsockname(c->sfd, c->laddr, &c->lport);
-}
-
-static void
-setlport(Conv *c)
-{
- if(c->restricted == 0 && c->lport == 0)
- return;
-
- if(c->sfd == -1)
- c->sfd = so_socket(c->p->stype, c->laddr);
-
- so_bind(c->sfd, c->restricted, c->lport, c->laddr);
-}
-
-static void
-setladdrport(Conv *c, char *str)
-{
- char *p;
- uchar addr[IPaddrlen];
-
- p = strchr(str, '!');
- if(p == 0) {
- p = str;
- ipzero(c->laddr);
- }
- else {
- *p++ = 0;
- parseip(addr, str);
- ipmove(c->laddr, addr);
- }
- if(*p == '*')
- c->lport = 0;
- else
- c->lport = atoi(p);
-
- setlport(c);
-}
-
-static char*
-setraddrport(Conv *c, char *str)
-{
- char *p;
- uchar addr[IPaddrlen];
-
- p = strchr(str, '!');
- if(p == 0)
- return "malformed address";
- *p++ = 0;
- parseip(addr, str);
- ipmove(c->raddr, addr);
- c->rport = atoi(p);
- p = strchr(p, '!');
- if(p) {
- if(strcmp(p, "!r") == 0)
- c->restricted = 1;
- }
- return 0;
-}
-
-long
-ipwrite(Chan *ch, void *a, long n, vlong offset)
-{
- Conv *c;
- Proto *x;
- int r, nf;
- char *p, *fields[3], buf[128];
-
- switch(TYPE(ch->qid)) {
- default:
- error(Eperm);
- case Qcs:
- return cswrite(ch, a, n, offset);
- case Qctl:
- x = &proto[PROTO(ch->qid)];
- c = x->conv[CONV(ch->qid)];
- if(n > sizeof(buf)-1)
- n = sizeof(buf)-1;
- memmove(buf, a, n);
- buf[n] = '\0';
-
- nf = tokenize(buf, fields, 3);
- if(strcmp(fields[0], "connect") == 0){
- switch(nf) {
- default:
- error("bad args to connect");
- case 2:
- p = setraddrport(c, fields[1]);
- if(p != 0)
- error(p);
- break;
- case 3:
- p = setraddrport(c, fields[1]);
- if(p != 0)
- error(p);
- c->lport = atoi(fields[2]);
- setlport(c);
- break;
- }
- if(c->sfd == -1)
- c->sfd = so_socket(c->p->stype, c->raddr);
- so_connect(c->sfd, c->raddr, c->rport);
- setladdr(c);
- c->state = "Established";
- return n;
- }
- if(strcmp(fields[0], "announce") == 0) {
- switch(nf){
- default:
- error("bad args to announce");
- case 2:
- setladdrport(c, fields[1]);
- break;
- }
- so_listen(c->sfd);
- c->state = "Announced";
- return n;
- }
- if(strcmp(fields[0], "bind") == 0){
- switch(nf){
- default:
- error("bad args to bind");
- case 2:
- c->lport = atoi(fields[1]);
- break;
- }
- setlport(c);
- return n;
- }
- error("bad control message");
- case Qdata:
- x = &proto[PROTO(ch->qid)];
- c = x->conv[CONV(ch->qid)];
- r = so_send(c->sfd, a, n, 0);
- if(r < 0){
- oserrstr();
- nexterror();
- }
- return r;
- }
- return n;
-}
-
-static Conv*
-protoclone(Proto *p, char *user, int nfd)
-{
- Conv *c, **pp, **ep;
-
- c = 0;
- lock(&p->l);
- if(waserror()) {
- unlock(&p->l);
- nexterror();
- }
- ep = &p->conv[p->maxconv];
- for(pp = p->conv; pp < ep; pp++) {
- c = *pp;
- if(c == 0) {
- c = mallocz(sizeof(Conv), 1);
- if(c == 0)
- error(Enomem);
- lock(&c->r.lk);
- c->r.ref = 1;
- c->p = p;
- c->x = pp - p->conv;
- p->nc++;
- *pp = c;
- break;
- }
- lock(&c->r.lk);
- if(c->r.ref == 0) {
- c->r.ref++;
- break;
- }
- unlock(&c->r.lk);
- }
- if(pp >= ep) {
- unlock(&p->l);
- poperror();
- return 0;
- }
-
- strcpy(c->owner, user);
- c->perm = 0660;
- c->state = "Closed";
- c->restricted = 0;
- ipzero(c->laddr);
- ipzero(c->raddr);
- c->lport = 0;
- c->rport = 0;
- c->sfd = nfd;
-
- unlock(&c->r.lk);
- unlock(&p->l);
- poperror();
- return c;
-}
-
-void
-csclose(Chan *c)
-{
- free(c->aux);
- c->aux = nil;
-}
-
-long
-csread(Chan *c, void *a, long n, vlong offset)
-{
- char *s, *e, *p;
-
- s = c->aux;
- if(s == nil)
- return 0;
- e = strchr(s, 0);
- s += offset;
- if(s >= e)
- return 0;
- p = strchr(s, '\n');
- if(p != nil)
- p++;
- else
- p = e;
- if(p - s < n)
- n = p - s;
- memmove(a, s, n);
- return n;
-}
-
-static struct
-{
- char *name;
- uint num;
-} tab[] = {
- "cs", 1,
- "echo", 7,
- "discard", 9,
- "systat", 11,
- "daytime", 13,
- "netstat", 15,
- "chargen", 19,
- "ftp-data", 20,
- "ftp", 21,
- "ssh", 22,
- "telnet", 23,
- "smtp", 25,
- "time", 37,
- "whois", 43,
- "dns", 53,
- "domain", 53,
- "uucp", 64,
- "gopher", 70,
- "rje", 77,
- "finger", 79,
- "http", 80,
- "link", 87,
- "supdup", 95,
- "hostnames", 101,
- "iso-tsap", 102,
- "x400", 103,
- "x400-snd", 104,
- "csnet-ns", 105,
- "pop-2", 109,
- "pop3", 110,
- "portmap", 111,
- "uucp-path", 117,
- "nntp", 119,
- "netbios", 139,
- "imap4", 143,
- "NeWS", 144,
- "print-srv", 170,
- "z39.50", 210,
- "fsb", 400,
- "sysmon", 401,
- "proxy", 402,
- "proxyd", 404,
- "https", 443,
- "cifs", 445,
- "ssmtp", 465,
- "rexec", 512,
- "login", 513,
- "shell", 514,
- "printer", 515,
- "courier", 530,
- "cscan", 531,
- "uucp", 540,
- "snntp", 563,
- "9fs", 564,
- "whoami", 565,
- "guard", 566,
- "ticket", 567,
- "dlsftp", 666,
- "fmclient", 729,
- "imaps", 993,
- "pop3s", 995,
- "ingreslock", 1524,
- "pptp", 1723,
- "nfs", 2049,
- "webster", 2627,
- "weather", 3000,
- "secstore", 5356,
- "Xdisplay", 6000,
- "styx", 6666,
- "mpeg", 6667,
- "rstyx", 6668,
- "infdb", 6669,
- "infsigner", 6671,
- "infcsigner", 6672,
- "inflogin", 6673,
- "bandt", 7330,
- "face", 32000,
- "dhashgate", 11978,
- "exportfs", 17007,
- "rexexec", 17009,
- "ncpu", 17010,
- "cpu", 17013,
- "rcpu", 17019,
- "t9fs", 17020,
- "glenglenda2", 17021,
- "glenglenda3", 17022,
- "glenglenda4", 17023,
- "glenglenda5", 17024,
- "glenglenda6", 17025,
- "glenglenda7", 17026,
- "glenglenda8", 17027,
- "glenglenda9", 17028,
- "glenglenda10", 17029,
- "flyboy", 17032,
- "dlsftp", 17033,
- "venti", 17034,
- "wiki", 17035,
- "vica", 17036,
- 0
-};
-
-static int
-lookupport(char *s)
-{
- int i;
- char buf[10], *p;
-
- i = strtol(s, &p, 0);
- if(*s && *p == 0)
- return i;
-
- i = so_getservbyname(s, "tcp", buf);
- if(i != -1)
- return atoi(buf);
- for(i=0; tab[i].name; i++)
- if(strcmp(s, tab[i].name) == 0)
- return tab[i].num;
- return 0;
-}
-
-long
-cswrite(Chan *c, void *a, long n, vlong offset)
-{
- char *f[4], *ips[8];
- char *s, *ns;
- uchar ip[IPaddrlen];
- int i, nf, port, nips;
-
- s = malloc(n+1);
- if(s == nil)
- error(Enomem);
- if(waserror()){
- free(s);
- nexterror();
- }
- memmove(s, a, n);
- s[n] = 0;
- nf = getfields(s, f, nelem(f), 0, "!");
- if(nf != 3)
- error("can't translate");
-
- port = lookupport(f[2]);
- if(port <= 0)
- error("no translation for port found");
- if(strcmp(f[0], "net") == 0)
- f[0] = "tcp";
- if(strcmp(f[1], "*") == 0){
- ns = smprint("/net/%s/clone %d", f[0], port);
- } else {
- if(parseip(ip, f[1]) != -1){
- ips[0] = smprint("%I", ip);
- nips = 1;
- } else {
- nips = so_gethostbyname(f[1], ips, nelem(ips));
- if(nips <= 0)
- error("no translation for host found");
- }
- ns = smprint("/net/%s/clone %s!%d", f[0], ips[0], port);
- free(ips[0]);
- for(i=1; i<nips; i++){
- ips[0] = smprint("%s\n/net/%s/clone %s!%d", ns, f[0], ips[i], port);
- free(ips[i]);
- free(ns);
- ns = ips[0];
- }
- }
- free(c->aux);
- c->aux = ns;
- poperror();
- free(s);
- return n;
-}
-
-Dev ipdevtab =
-{
- 'I',
- "ip",
-
- devreset,
- ipinit,
- devshutdown,
- ipattach,
- ipwalk,
- ipstat,
- ipopen,
- devcreate,
- ipclose,
- ipread,
- devbread,
- ipwrite,
- devbwrite,
- devremove,
- devwstat,
-};
-
--- a/kern/devkbd.c
+++ /dev/null
@@ -1,141 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-
-static Queue* keyq;
-static int kbdinuse;
-
-void
-kbdkey(Rune r, int down)
-{
- char buf[2+UTFmax];
-
- if(r == 0)
- return;
-
- if(!kbdinuse || keyq == nil){
- if(down)
- kbdputc(kbdq, r); /* /dev/cons */
- return;
- }
-
- memset(buf, 0, sizeof buf);
- buf[0] = down ? 'r' : 'R';
- qproduce(keyq, buf, 2+runetochar(buf+1, &r));
-}
-
-enum{
- Qdir,
- Qkbd,
-};
-
-static Dirtab kbddir[]={
- ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
- "kbd", {Qkbd}, 0, 0444,
-};
-
-static void
-kbdinit(void)
-{
- keyq = qopen(4*1024, Qcoalesce, 0, 0);
- if(keyq == nil)
- panic("kbdinit");
- qnoblock(keyq, 1);
-}
-
-static Chan*
-kbdattach(char *spec)
-{
- return devattach('b', spec);
-}
-
-static Walkqid*
-kbdwalk(Chan *c, Chan *nc, char **name, int nname)
-{
- return devwalk(c, nc, name,nname, kbddir, nelem(kbddir), devgen);
-}
-
-static int
-kbdstat(Chan *c, uchar *dp, int n)
-{
- return devstat(c, dp, n, kbddir, nelem(kbddir), devgen);
-}
-
-static Chan*
-kbdopen(Chan *c, int omode)
-{
- c = devopen(c, omode, kbddir, nelem(kbddir), devgen);
- switch((ulong)c->qid.path){
- case Qkbd:
- if(tas(&kbdinuse) != 0){
- c->flag &= ~COPEN;
- error(Einuse);
- }
- break;
- }
- return c;
-}
-
-static void
-kbdclose(Chan *c)
-{
- switch((ulong)c->qid.path){
- case Qkbd:
- if(c->flag&COPEN)
- kbdinuse = 0;
- break;
- }
-}
-
-static long
-kbdread(Chan *c, void *buf, long n, vlong off)
-{
- USED(off);
-
- if(n <= 0)
- return n;
- switch((ulong)c->qid.path){
- case Qdir:
- return devdirread(c, buf, n, kbddir, nelem(kbddir), devgen);
- case Qkbd:
- return qread(keyq, buf, n);
- default:
- print("kbdread 0x%llux\n", c->qid.path);
- error(Egreg);
- }
- return -1; /* never reached */
-}
-
-static long
-kbdwrite(Chan *c, void *va, long n, vlong off)
-{
- USED(c);
- USED(va);
- USED(n);
- USED(off);
- error(Eperm);
- return -1; /* never reached */
-}
-
-Dev kbddevtab = {
- 'b',
- "kbd",
-
- devreset,
- kbdinit,
- devshutdown,
- kbdattach,
- kbdwalk,
- kbdstat,
- kbdopen,
- devcreate,
- kbdclose,
- kbdread,
- devbread,
- kbdwrite,
- devbwrite,
- devremove,
- devwstat,
-};
--- a/kern/devmouse.c
+++ /dev/null
@@ -1,391 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-
-#include "draw.h"
-#include "memdraw.h"
-#include "screen.h"
-
-Mouseinfo mouse;
-Cursorinfo cursor;
-Cursorinfo arrow = {
- .lk = 0,
- .offset = { -1, -1 },
- .clr = { 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C,
- 0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04,
- 0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8C, 0x04,
- 0x92, 0x08, 0x91, 0x10, 0xA0, 0xA0, 0xC0, 0x40,
- },
- .set = { 0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0,
- 0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8,
- 0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8,
- 0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00,
- },
-};
-
-static uchar buttonmap[8] = {0,1,2,3,4,5,6,7,};
-static int mouseswap;
-static int scrollswap;
-
-static int mousechanged(void*);
-
-enum {
- CMbuttonmap,
- CMscrollswap,
- CMswap,
-};
-
-static Cmdtab mousectlmsg[] =
-{
- CMbuttonmap, "buttonmap", 0,
- CMscrollswap, "scrollswap", 0,
- CMswap, "swap", 1,
-};
-
-enum {
- Qdir,
- Qcursor,
- Qmouse,
- Qmousectl
-};
-
-Dirtab mousedir[]={
- ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
- "cursor", {Qcursor}, 0, 0666,
- "mouse", {Qmouse}, 0, 0666,
- "mousectl", {Qmousectl}, 0, 0222,
-};
-
-#define NMOUSE (sizeof(mousedir)/sizeof(Dirtab))
-
-static void
-mouseinit(void)
-{
- cursor = arrow;
-}
-
-static Chan*
-mouseattach(char *spec)
-{
- setcursor();
- return devattach('m', spec);
-}
-
-static Walkqid*
-mousewalk(Chan *c, Chan *nc, char **name, int nname)
-{
- return devwalk(c, nc, name, nname, mousedir, NMOUSE, devgen);
-}
-
-static int
-mousestat(Chan *c, uchar *db, int n)
-{
- return devstat(c, db, n, mousedir, NMOUSE, devgen);
-}
-
-static Chan*
-mouseopen(Chan *c, int omode)
-{
- switch((long)c->qid.path){
- case Qdir:
- if(omode != OREAD)
- error(Eperm);
- break;
- case Qmouse:
- if(tas(&mouse.open) != 0)
- error(Einuse);
- mouse.resize = 0;
- mouse.lastcounter = mouse.state.counter;
- break;
- }
- c->mode = openmode(omode);
- c->flag |= COPEN;
- c->offset = 0;
- return c;
-}
-
-void
-mouseclose(Chan *c)
-{
- if(!(c->flag&COPEN))
- return;
-
- switch((long)c->qid.path) {
- case Qmouse:
- mouse.open = 0;
- cursor = arrow;
- setcursor();
- }
-}
-
-long
-mouseread(Chan *c, void *va, long n, vlong offset)
-{
- char buf[1+4*12+1];
- Mousestate m;
- uchar *p;
- int b;
-
- p = va;
- switch((long)c->qid.path){
- case Qdir:
- return devdirread(c, va, n, mousedir, NMOUSE, devgen);
-
- case Qcursor:
- if(offset != 0)
- return 0;
- if(n < 2*4+2*2*16)
- error(Eshort);
- n = 2*4+2*2*16;
- lock(&cursor.lk);
- BPLONG(p+0, cursor.offset.x);
- BPLONG(p+4, cursor.offset.y);
- memmove(p+8, cursor.clr, 2*16);
- memmove(p+40, cursor.set, 2*16);
- unlock(&cursor.lk);
- return n;
-
- case Qmouse:
- while(mousechanged(0) == 0)
- sleep(&mouse.r, mousechanged, 0);
-
- lock(&mouse.lk);
- if(mouse.ri != mouse.wi)
- m = mouse.queue[mouse.ri++ % nelem(mouse.queue)];
- else
- m = mouse.state;
- unlock(&mouse.lk);
-
- b = buttonmap[m.buttons&7];
- /* put buttons 4 and 5 back in */
- b |= m.buttons & (3<<3);
- if (scrollswap) {
- if (b == 8)
- b = 16;
- else if (b == 16)
- b = 8;
- }
- sprint(buf, "m%11d %11d %11d %11ld ",
- m.xy.x, m.xy.y, b, m.msec);
-
- mouse.lastcounter = m.counter;
- if(mouse.resize){
- mouse.resize = 0;
- buf[0] = 'r';
- }
-
- if(n > 1+4*12)
- n = 1+4*12;
- memmove(va, buf, n);
- return n;
- }
- return 0;
-}
-
-static void
-setbuttonmap(char* map)
-{
- int i, x, one, two, three;
-
- one = two = three = 0;
- for(i = 0; i < 3; i++){
- if(map[i] == 0)
- error(Ebadarg);
- if(map[i] == '1'){
- if(one)
- error(Ebadarg);
- one = 1<<i;
- }
- else if(map[i] == '2'){
- if(two)
- error(Ebadarg);
- two = 1<<i;
- }
- else if(map[i] == '3'){
- if(three)
- error(Ebadarg);
- three = 1<<i;
- }
- else
- error(Ebadarg);
- }
- if(map[i])
- error(Ebadarg);
-
- memset(buttonmap, 0, 8);
- for(i = 0; i < 8; i++){
- x = 0;
- if(i & 1)
- x |= one;
- if(i & 2)
- x |= two;
- if(i & 4)
- x |= three;
- buttonmap[x] = i;
- }
-}
-
-long
-mousewrite(Chan *c, void *va, long n, vlong offset)
-{
- char *p;
- Point pt;
- char buf[64];
- Cmdbuf *cb;
- Cmdtab *ct;
-
- USED(offset);
-
- p = va;
- switch((long)c->qid.path){
- case Qdir:
- error(Eisdir);
-
- case Qcursor:
- if(n < 2*4+2*2*16){
- cursor = arrow;
- setcursor();
- }else{
- n = 2*4+2*2*16;
- lock(&cursor.lk);
- cursor.offset.x = BGLONG(p+0);
- cursor.offset.y = BGLONG(p+4);
- memmove(cursor.clr, p+8, 2*16);
- memmove(cursor.set, p+40, 2*16);
- unlock(&cursor.lk);
- setcursor();
- }
- return n;
-
- case Qmouse:
- if(n > sizeof buf-1)
- n = sizeof buf -1;
- memmove(buf, va, n);
- buf[n] = 0;
- p = 0;
- pt.x = strtoul(buf+1, &p, 0);
- if(p == 0)
- error(Eshort);
- pt.y = strtoul(p, 0, 0);
- if(ptinrect(pt, gscreen->r))
- mouseset(pt);
- return n;
-
- case Qmousectl:
- cb = parsecmd(va,n);
- if(waserror()){
- free(cb);
- nexterror();
- }
- ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));
- switch(ct->index){
- case CMswap:
- if(mouseswap)
- setbuttonmap("123");
- else
- setbuttonmap("321");
- mouseswap ^= 1;
- break;
-
- case CMscrollswap:
- scrollswap ^= 1;
- break;
-
- case CMbuttonmap:
- if(cb->nf==1)
- setbuttonmap("123");
- else
- setbuttonmap(cb->f[1]);
- break;
- }
- free(cb);
- poperror();
- return n;
- }
-
- error(Egreg);
- return -1;
-}
-
-/*
- * notify reader that screen has been resized
- */
-void
-mouseresize(void)
-{
- mouse.resize = 1;
- wakeup(&mouse.r);
-}
-
-int
-mousechanged(void *a)
-{
- USED(a);
- return mouse.lastcounter != mouse.state.counter || mouse.resize;
-}
-
-void
-mousetrack(int dx, int dy, int b, ulong msec)
-{
- absmousetrack(mouse.state.xy.x + dx, mouse.state.xy.y + dy, b, msec);
-}
-
-void
-absmousetrack(int x, int y, int b, ulong msec)
-{
- int lastb;
-
- if(gscreen==nil)
- return;
-
- if(x < gscreen->clipr.min.x)
- x = gscreen->clipr.min.x;
- if(x >= gscreen->clipr.max.x)
- x = gscreen->clipr.max.x-1;
- if(y < gscreen->clipr.min.y)
- y = gscreen->clipr.min.y;
- if(y >= gscreen->clipr.max.y)
- y = gscreen->clipr.max.y-1;
-
- lock(&mouse.lk);
- mouse.state.xy = Pt(x, y);
- lastb = mouse.state.buttons;
- mouse.state.buttons = b;
- mouse.state.msec = msec;
- mouse.state.counter++;
-
- /*
- * if the queue fills, don't queue any more events until a
- * reader polls the mouse.
- */
- if(b != lastb && (mouse.wi-mouse.ri) < nelem(mouse.queue))
- mouse.queue[mouse.wi++ % nelem(mouse.queue)] = mouse.state;
- unlock(&mouse.lk);
-
- wakeup(&mouse.r);
-}
-
-Dev mousedevtab = {
- 'm',
- "mouse",
-
- devreset,
- mouseinit,
- devshutdown,
- mouseattach,
- mousewalk,
- mousestat,
- mouseopen,
- devcreate,
- mouseclose,
- mouseread,
- devbread,
- mousewrite,
- devbwrite,
- devremove,
- devwstat,
-};
-
-
--- a/kern/devssl.c
+++ /dev/null
@@ -1,1450 +1,0 @@
-/*
- * devssl - secure sockets layer
- */
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-
-#include <libsec.h>
-
-typedef struct OneWay OneWay;
-struct OneWay
-{
- QLock q;
- QLock ctlq;
-
- void *state; /* encryption state */
- int slen; /* hash data length */
- uchar *secret; /* secret */
- ulong mid; /* message id */
-};
-
-enum
-{
- /* connection states */
- Sincomplete= 0,
- Sclear= 1,
- Sencrypting= 2,
- Sdigesting= 4,
- Sdigenc= Sencrypting|Sdigesting,
-
- /* encryption algorithms */
- Noencryption= 0,
- DESCBC= 1,
- DESECB= 2,
- RC4= 3
-};
-
-typedef struct Dstate Dstate;
-struct Dstate
-{
- Chan *c; /* io channel */
- uchar state; /* state of connection */
- int ref; /* serialized by dslock for atomic destroy */
-
- uchar encryptalg; /* encryption algorithm */
- ushort blocklen; /* blocking length */
-
- ushort diglen; /* length of digest */
- DigestState *(*hf)(uchar*, ulong, uchar*, DigestState*); /* hash func */
-
- /* for SSL format */
- int max; /* maximum unpadded data per msg */
- int maxpad; /* maximum padded data per msg */
-
- /* input side */
- OneWay in;
- Block *processed;
- Block *unprocessed;
-
- /* output side */
- OneWay out;
-
- /* protections */
- char *user;
- int perm;
-};
-
-enum
-{
- Maxdmsg= 1<<16,
- Maxdstate= 512, /* max. open ssl conn's; must be a power of 2 */
-};
-
-static Lock dslock;
-static int dshiwat;
-static char *dsname[Maxdstate];
-static Dstate *dstate[Maxdstate];
-static char *encalgs;
-static char *hashalgs;
-
-enum{
- Qtopdir = 1, /* top level directory */
- Qprotodir,
- Qclonus,
- Qconvdir, /* directory for a conversation */
- Qdata,
- Qctl,
- Qsecretin,
- Qsecretout,
- Qencalgs,
- Qhashalgs,
-};
-
-#define TYPE(x) ((x).path & 0xf)
-#define CONV(x) (((x).path >> 5)&(Maxdstate-1))
-#define QID(c, y) (((c)<<5) | (y))
-
-static void ensure(Dstate*, Block**, int);
-static void consume(Block**, uchar*, int);
-static void setsecret(OneWay*, uchar*, int);
-static Block* encryptb(Dstate*, Block*, int);
-static Block* decryptb(Dstate*, Block*);
-static Block* digestb(Dstate*, Block*, int);
-static void checkdigestb(Dstate*, Block*);
-static Chan* buftochan(char*);
-static void sslhangup(Dstate*);
-static Dstate* dsclone(Chan *c);
-static void dsnew(Chan *c, Dstate **);
-static long sslput(Dstate *s, Block * volatile b);
-
-char *sslnames[] = {
-[Qclonus] "clone",
-[Qdata] "data",
-[Qctl] "ctl",
-[Qsecretin] "secretin",
-[Qsecretout] "secretout",
-[Qencalgs] "encalgs",
-[Qhashalgs] "hashalgs",
-};
-
-static int
-sslgen(Chan *c, char *n, Dirtab *d, int nd, int s, Dir *dp)
-{
- Qid q;
- Dstate *ds;
- char name[16], *p, *nm;
- int ft;
-
- USED(n);
- USED(nd);
- USED(d);
-
- q.type = QTFILE;
- q.vers = 0;
-
- ft = TYPE(c->qid);
- switch(ft) {
- case Qtopdir:
- if(s == DEVDOTDOT){
- q.path = QID(0, Qtopdir);
- q.type = QTDIR;
- devdir(c, q, "#D", 0, eve, 0555, dp);
- return 1;
- }
- if(s > 0)
- return -1;
- q.path = QID(0, Qprotodir);
- q.type = QTDIR;
- devdir(c, q, "ssl", 0, eve, 0555, dp);
- return 1;
- case Qprotodir:
- if(s == DEVDOTDOT){
- q.path = QID(0, Qtopdir);
- q.type = QTDIR;
- devdir(c, q, ".", 0, eve, 0555, dp);
- return 1;
- }
- if(s < dshiwat) {
- q.path = QID(s, Qconvdir);
- q.type = QTDIR;
- ds = dstate[s];
- if(ds != 0)
- nm = ds->user;
- else
- nm = eve;
- if(dsname[s] == nil){
- sprint(name, "%d", s);
- kstrdup(&dsname[s], name);
- }
- devdir(c, q, dsname[s], 0, nm, 0555, dp);
- return 1;
- }
- if(s > dshiwat)
- return -1;
- q.path = QID(0, Qclonus);
- devdir(c, q, "clone", 0, eve, 0555, dp);
- return 1;
- case Qconvdir:
- if(s == DEVDOTDOT){
- q.path = QID(0, Qprotodir);
- q.type = QTDIR;
- devdir(c, q, "ssl", 0, eve, 0555, dp);
- return 1;
- }
- ds = dstate[CONV(c->qid)];
- if(ds != 0)
- nm = ds->user;
- else
- nm = eve;
- switch(s) {
- default:
- return -1;
- case 0:
- q.path = QID(CONV(c->qid), Qctl);
- p = "ctl";
- break;
- case 1:
- q.path = QID(CONV(c->qid), Qdata);
- p = "data";
- break;
- case 2:
- q.path = QID(CONV(c->qid), Qsecretin);
- p = "secretin";
- break;
- case 3:
- q.path = QID(CONV(c->qid), Qsecretout);
- p = "secretout";
- break;
- case 4:
- q.path = QID(CONV(c->qid), Qencalgs);
- p = "encalgs";
- break;
- case 5:
- q.path = QID(CONV(c->qid), Qhashalgs);
- p = "hashalgs";
- break;
- }
- devdir(c, q, p, 0, nm, 0660, dp);
- return 1;
- case Qclonus:
- devdir(c, c->qid, sslnames[TYPE(c->qid)], 0, eve, 0555, dp);
- return 1;
- default:
- ds = dstate[CONV(c->qid)];
- if(ds != 0)
- nm = ds->user;
- else
- nm = eve;
- devdir(c, c->qid, sslnames[TYPE(c->qid)], 0, nm, 0660, dp);
- return 1;
- }
-}
-
-static Chan*
-sslattach(char *spec)
-{
- Chan *c;
-
- c = devattach('D', spec);
- c->qid.path = QID(0, Qtopdir);
- c->qid.vers = 0;
- c->qid.type = QTDIR;
- return c;
-}
-
-static Walkqid*
-sslwalk(Chan *c, Chan *nc, char **name, int nname)
-{
- return devwalk(c, nc, name, nname, nil, 0, sslgen);
-}
-
-static int
-sslstat(Chan *c, uchar *db, int n)
-{
- return devstat(c, db, n, nil, 0, sslgen);
-}
-
-static Chan*
-sslopen(Chan *c, int omode)
-{
- Dstate *s, **pp;
- int ft;
-
- ft = TYPE(c->qid);
- switch(ft) {
- default:
- panic("sslopen");
- case Qtopdir:
- case Qprotodir:
- case Qconvdir:
- if(omode != OREAD)
- error(Eperm);
- break;
- case Qclonus:
- s = dsclone(c);
- if(s == 0)
- error(Enodev);
- break;
- case Qctl:
- case Qdata:
- case Qsecretin:
- case Qsecretout:
- if(waserror()) {
- unlock(&dslock);
- nexterror();
- }
- lock(&dslock);
- pp = &dstate[CONV(c->qid)];
- s = *pp;
- if(s == 0)
- dsnew(c, pp);
- else {
- devpermcheck(s->user, s->perm, omode);
- s->ref++;
- }
- unlock(&dslock);
- poperror();
- break;
- case Qencalgs:
- case Qhashalgs:
- if(omode != OREAD)
- error(Eperm);
- break;
- }
- c->mode = openmode(omode);
- c->flag |= COPEN;
- c->offset = 0;
- return c;
-}
-
-static int
-sslwstat(Chan *c, uchar *db, int n)
-{
- Dir *dir;
- Dstate *s;
- int m;
-
- s = dstate[CONV(c->qid)];
- if(s == 0)
- error(Ebadusefd);
- if(strcmp(s->user, up->user) != 0)
- error(Eperm);
-
- dir = smalloc(sizeof(Dir)+n);
- m = convM2D(db, n, &dir[0], (char*)&dir[1]);
- if(m == 0){
- free(dir);
- error(Eshortstat);
- }
-
- if(!emptystr(dir->uid))
- kstrdup(&s->user, dir->uid);
- if(dir->mode != -1)
- s->perm = dir->mode;
-
- free(dir);
- return m;
-}
-
-static void
-sslclose(Chan *c)
-{
- Dstate *s;
- int ft;
-
- ft = TYPE(c->qid);
- switch(ft) {
- case Qctl:
- case Qdata:
- case Qsecretin:
- case Qsecretout:
- if((c->flag & COPEN) == 0)
- break;
-
- s = dstate[CONV(c->qid)];
- if(s == 0)
- break;
-
- lock(&dslock);
- if(--s->ref > 0) {
- unlock(&dslock);
- break;
- }
- dstate[CONV(c->qid)] = 0;
- unlock(&dslock);
-
- if(s->user != nil)
- free(s->user);
- sslhangup(s);
- if(s->c)
- cclose(s->c);
- secfree(s->in.secret);
- secfree(s->out.secret);
- secfree(s->in.state);
- secfree(s->out.state);
- free(s);
-
- }
-}
-
-/*
- * make sure we have at least 'n' bytes in list 'l'
- */
-static void
-ensure(Dstate *s, Block **l, int n)
-{
- int sofar, i;
- Block *b, *bl;
-
- sofar = 0;
- for(b = *l; b; b = b->next){
- sofar += BLEN(b);
- if(sofar >= n)
- return;
- l = &b->next;
- }
-
- while(sofar < n){
- bl = devtab[s->c->type]->bread(s->c, Maxdmsg, 0);
- if(bl == 0)
- nexterror();
- *l = bl;
- i = 0;
- for(b = bl; b; b = b->next){
- i += BLEN(b);
- l = &b->next;
- }
- if(i == 0)
- error(Ehungup);
- sofar += i;
- }
-}
-
-/*
- * copy 'n' bytes from 'l' into 'p' and free
- * the bytes in 'l'
- */
-static void
-consume(Block **l, uchar *p, int n)
-{
- Block *b;
- int i;
-
- for(; *l && n > 0; n -= i){
- b = *l;
- i = BLEN(b);
- if(i > n)
- i = n;
- memmove(p, b->rp, i);
- b->rp += i;
- p += i;
- if(BLEN(b) < 0)
- panic("consume");
- if(BLEN(b))
- break;
- *l = b->next;
- freeb(b);
- }
-}
-
-/*
- * give back n bytes
-static void
-regurgitate(Dstate *s, uchar *p, int n)
-{
- Block *b;
-
- if(n <= 0)
- return;
- b = s->unprocessed;
- if(s->unprocessed == nil || b->rp - b->base < n) {
- b = allocb(n);
- memmove(b->wp, p, n);
- b->wp += n;
- b->next = s->unprocessed;
- s->unprocessed = b;
- } else {
- b->rp -= n;
- memmove(b->rp, p, n);
- }
-}
- */
-
-/*
- * remove at most n bytes from the queue, if discard is set
- * dump the remainder
- */
-static Block*
-qtake(Block **l, int n, int discard)
-{
- Block *nb, *b, *first;
- int i;
-
- first = *l;
- for(b = first; b; b = b->next){
- i = BLEN(b);
- if(i == n){
- if(discard){
- freeblist(b->next);
- *l = 0;
- } else
- *l = b->next;
- b->next = 0;
- return first;
- } else if(i > n){
- i -= n;
- if(discard){
- freeblist(b->next);
- b->wp -= i;
- *l = 0;
- } else {
- nb = allocb(i);
- memmove(nb->wp, b->rp+n, i);
- nb->wp += i;
- b->wp -= i;
- nb->next = b->next;
- *l = nb;
- }
- b->next = 0;
- if(BLEN(b) < 0)
- panic("qtake");
- return first;
- } else
- n -= i;
- if(BLEN(b) < 0)
- panic("qtake");
- }
- *l = 0;
- return first;
-}
-
-/*
- * We can't let Eintr's lose data since the program
- * doing the read may be able to handle it. The only
- * places Eintr is possible is during the read's in consume.
- * Therefore, we make sure we can always put back the bytes
- * consumed before the last ensure.
- */
-static Block*
-sslbread(Chan *c, long n, ulong o)
-{
- Dstate * volatile s;
- Block *b;
- uchar consumed[3], *p;
- int toconsume;
- int len, pad;
-
- USED(o);
- s = dstate[CONV(c->qid)];
- if(s == 0)
- panic("sslbread");
- if(s->state == Sincomplete)
- error(Ebadusefd);
-
- qlock(&s->in.q);
- if(waserror()){
- qunlock(&s->in.q);
- nexterror();
- }
-
- if(s->processed == 0){
- /*
- * Read in the whole message. Until we've got it all,
- * it stays on s->unprocessed, so that if we get Eintr,
- * we'll pick up where we left off.
- */
- ensure(s, &s->unprocessed, 3);
- s->unprocessed = pullupblock(s->unprocessed, 2);
- p = s->unprocessed->rp;
- if(p[0] & 0x80){
- len = ((p[0] & 0x7f)<<8) | p[1];
- ensure(s, &s->unprocessed, len);
- pad = 0;
- toconsume = 2;
- } else {
- s->unprocessed = pullupblock(s->unprocessed, 3);
- len = ((p[0] & 0x3f)<<8) | p[1];
- pad = p[2];
- if(pad > len){
- print("pad %d buf len %d\n", pad, len);
- error("bad pad in ssl message");
- }
- toconsume = 3;
- }
- ensure(s, &s->unprocessed, toconsume+len);
-
- /* skip header */
- consume(&s->unprocessed, consumed, toconsume);
-
- /* grab the next message and decode/decrypt it */
- b = qtake(&s->unprocessed, len, 0);
-
- if(blocklen(b) != len)
- print("devssl: sslbread got wrong count %d != %d", blocklen(b), len);
-
- if(waserror()){
- qunlock(&s->in.ctlq);
- if(b != nil)
- freeb(b);
- nexterror();
- }
- qlock(&s->in.ctlq);
- switch(s->state){
- case Sencrypting:
- if(b == nil)
- error("ssl message too short (encrypting)");
- b = decryptb(s, b);
- break;
- case Sdigesting:
- b = pullupblock(b, s->diglen);
- if(b == nil)
- error("ssl message too short (digesting)");
- checkdigestb(s, b);
- pullblock(&b, s->diglen);
- len -= s->diglen;
- break;
- case Sdigenc:
- b = decryptb(s, b);
- b = pullupblock(b, s->diglen);
- if(b == nil)
- error("ssl message too short (dig+enc)");
- checkdigestb(s, b);
- pullblock(&b, s->diglen);
- len -= s->diglen;
- break;
- }
-
- /* remove pad */
- if(pad)
- s->processed = qtake(&b, len - pad, 1);
- else
- s->processed = b;
- b = nil;
- s->in.mid++;
- qunlock(&s->in.ctlq);
- poperror();
- }
-
- /* return at most what was asked for */
- b = qtake(&s->processed, n, 0);
-
- qunlock(&s->in.q);
- poperror();
-
- return b;
-}
-
-static long
-sslread(Chan *c, void *a, long n, vlong off)
-{
- Block * volatile b;
- Block *nb;
- uchar *va;
- int i;
- char buf[128];
- ulong offset = off;
- int ft;
-
- if(c->qid.type & QTDIR)
- return devdirread(c, a, n, 0, 0, sslgen);
-
- ft = TYPE(c->qid);
- switch(ft) {
- default:
- error(Ebadusefd);
- case Qctl:
- ft = CONV(c->qid);
- sprint(buf, "%d", ft);
- return readstr(offset, a, n, buf);
- case Qdata:
- b = sslbread(c, n, offset);
- break;
- case Qencalgs:
- return readstr(offset, a, n, encalgs);
- break;
- case Qhashalgs:
- return readstr(offset, a, n, hashalgs);
- break;
- }
-
- if(waserror()){
- freeblist(b);
- nexterror();
- }
-
- n = 0;
- va = a;
- for(nb = b; nb; nb = nb->next){
- i = BLEN(nb);
- memmove(va+n, nb->rp, i);
- n += i;
- }
-
- freeblist(b);
- poperror();
-
- return n;
-}
-
-static long
-sslbwrite(Chan *c, Block *b, ulong o)
-{
- Dstate * volatile s;
- long rv;
-
- USED(o);
- s = dstate[CONV(c->qid)];
- if(s == nil)
- panic("sslbwrite");
-
- if(s->state == Sincomplete){
- freeb(b);
- error(Ebadusefd);
- }
-
- /* lock so split writes won't interleave */
- if(waserror()){
- qunlock(&s->out.q);
- nexterror();
- }
- qlock(&s->out.q);
-
- rv = sslput(s, b);
-
- poperror();
- qunlock(&s->out.q);
-
- return rv;
-}
-
-/*
- * use SSL record format, add in count, digest and/or encrypt.
- * the write is interruptable. if it is interrupted, we'll
- * get out of sync with the far side. not much we can do about
- * it since we don't know if any bytes have been written.
- */
-static long
-sslput(Dstate *s, Block * volatile b)
-{
- Block *nb;
- int h, n, m, pad, rv;
- uchar *p;
- int offset;
-
- if(waserror()){
- if(b != nil)
- freeb(b);
- nexterror();
- }
-
- rv = 0;
- while(b != nil){
- m = n = BLEN(b);
- h = s->diglen + 2;
-
- /* trim to maximum block size */
- pad = 0;
- if(m > s->max){
- m = s->max;
- } else if(s->blocklen != 1){
- pad = (m + s->diglen)%s->blocklen;
- if(pad){
- if(m > s->maxpad){
- pad = 0;
- m = s->maxpad;
- } else {
- pad = s->blocklen - pad;
- h++;
- }
- }
- }
-
- rv += m;
- if(m != n){
- nb = allocb(m + h + pad);
- memmove(nb->wp + h, b->rp, m);
- nb->wp += m + h;
- b->rp += m;
- } else {
- /* add header space */
- nb = padblock(b, h);
- b = 0;
- }
- m += s->diglen;
-
- /* SSL style count */
- if(pad){
- nb = padblock(nb, -pad);
- prng(nb->wp, pad);
- nb->wp += pad;
- m += pad;
-
- p = nb->rp;
- p[0] = (m>>8);
- p[1] = m;
- p[2] = pad;
- offset = 3;
- } else {
- p = nb->rp;
- p[0] = (m>>8) | 0x80;
- p[1] = m;
- offset = 2;
- }
-
- switch(s->state){
- case Sencrypting:
- nb = encryptb(s, nb, offset);
- break;
- case Sdigesting:
- nb = digestb(s, nb, offset);
- break;
- case Sdigenc:
- nb = digestb(s, nb, offset);
- nb = encryptb(s, nb, offset);
- break;
- }
-
- s->out.mid++;
-
- m = BLEN(nb);
- devtab[s->c->type]->bwrite(s->c, nb, s->c->offset);
- s->c->offset += m;
- }
-
- poperror();
- return rv;
-}
-
-static void
-setsecret(OneWay *w, uchar *secret, int n)
-{
- secfree(w->secret);
- w->secret = secalloc(n);
- memmove(w->secret, secret, n);
- w->slen = n;
-}
-
-static void
-initDESkey(OneWay *w)
-{
- secfree(w->state);
- w->state = secalloc(sizeof(DESstate));
- if(w->slen >= 16)
- setupDESstate(w->state, w->secret, w->secret+8);
- else if(w->slen >= 8)
- setupDESstate(w->state, w->secret, 0);
- else
- error("secret too short");
-}
-
-/*
- * 40 bit DES is the same as 56 bit DES. However,
- * 16 bits of the key are masked to zero.
- */
-static void
-initDESkey_40(OneWay *w)
-{
- uchar key[8];
-
- if(w->slen >= 8){
- memmove(key, w->secret, 8);
- key[0] &= 0x0f;
- key[2] &= 0x0f;
- key[4] &= 0x0f;
- key[6] &= 0x0f;
- }
- initDESkey(w);
-}
-
-static void
-initRC4key(OneWay *w)
-{
- secfree(w->state);
- w->state = secalloc(sizeof(RC4state));
- setupRC4state(w->state, w->secret, w->slen);
-}
-
-/*
- * 40 bit RC4 is the same as n-bit RC4. However,
- * we ignore all but the first 40 bits of the key.
- */
-static void
-initRC4key_40(OneWay *w)
-{
- if(w->slen > 5)
- w->slen = 5;
- initRC4key(w);
-}
-
-/*
- * 128 bit RC4 is the same as n-bit RC4. However,
- * we ignore all but the first 128 bits of the key.
- */
-static void
-initRC4key_128(OneWay *w)
-{
- if(w->slen > 16)
- w->slen = 16;
- initRC4key(w);
-}
-
-
-typedef struct Hashalg Hashalg;
-struct Hashalg
-{
- char *name;
- int diglen;
- DigestState *(*hf)(uchar*, ulong, uchar*, DigestState*);
-};
-
-Hashalg hashtab[] =
-{
- { "md5", MD5dlen, md5, },
- { "sha1", SHA1dlen, sha1, },
- { "sha", SHA1dlen, sha1, },
- { 0 }
-};
-
-static int
-parsehashalg(char *p, Dstate *s)
-{
- Hashalg *ha;
-
- for(ha = hashtab; ha->name; ha++){
- if(strcmp(p, ha->name) == 0){
- s->hf = ha->hf;
- s->diglen = ha->diglen;
- s->state &= ~Sclear;
- s->state |= Sdigesting;
- return 0;
- }
- }
- return -1;
-}
-
-typedef struct Encalg Encalg;
-struct Encalg
-{
- char *name;
- int blocklen;
- int alg;
- void (*keyinit)(OneWay*);
-};
-
-static
-Encalg encrypttab[] =
-{
- { "descbc", 8, DESCBC, initDESkey, }, /* DEPRECATED -- use des_56_cbc */
- { "desecb", 8, DESECB, initDESkey, }, /* DEPRECATED -- use des_56_ecb */
- { "des_56_cbc", 8, DESCBC, initDESkey, },
- { "des_56_ecb", 8, DESECB, initDESkey, },
- { "des_40_cbc", 8, DESCBC, initDESkey_40, },
- { "des_40_ecb", 8, DESECB, initDESkey_40, },
- { "rc4", 1, RC4, initRC4key_40, }, /* DEPRECATED -- use rc4_X */
- { "rc4_256", 1, RC4, initRC4key, },
- { "rc4_128", 1, RC4, initRC4key_128, },
- { "rc4_40", 1, RC4, initRC4key_40, },
- { 0 }
-};
-
-static int
-parseencryptalg(char *p, Dstate *s)
-{
- Encalg *ea;
-
- for(ea = encrypttab; ea->name; ea++){
- if(strcmp(p, ea->name) == 0){
- s->encryptalg = ea->alg;
- s->blocklen = ea->blocklen;
- (*ea->keyinit)(&s->in);
- (*ea->keyinit)(&s->out);
- s->state &= ~Sclear;
- s->state |= Sencrypting;
- return 0;
- }
- }
- return -1;
-}
-
-enum {
- Cfd,
- Calg,
- Csin,
- Csout,
-};
-
-static
-Cmdtab sslcmds[] = {
- {Cfd, "fd", 2 },
- {Calg, "alg", 0 },
- {Csin, "secretin", 2 },
- {Csout, "secretout", 2 },
-};
-
-static long
-sslwrite(Chan *c, void *a, long n, vlong o)
-{
- Dstate * volatile s;
- Block * volatile b;
- int m, t, i;
- char *p, *e;
- uchar *x;
- Cmdbuf *cb;
- Cmdtab *ct;
-
- USED(o);
- s = dstate[CONV(c->qid)];
- if(s == 0)
- panic("sslwrite");
-
- t = TYPE(c->qid);
- if(t == Qdata){
- if(s->state == Sincomplete)
- error(Ebadusefd);
-
- /* lock should a write gets split over multiple records */
- if(waserror()){
- qunlock(&s->out.q);
- nexterror();
- }
- qlock(&s->out.q);
-
- p = a;
- e = p + n;
- do {
- m = e - p;
- if(m > s->max)
- m = s->max;
-
- b = allocb(m);
- if(waserror()){
- freeb(b);
- nexterror();
- }
- memmove(b->wp, p, m);
- poperror();
- b->wp += m;
-
- sslput(s, b);
-
- p += m;
- } while(p < e);
-
- poperror();
- qunlock(&s->out.q);
- return n;
- }
-
- /* mutex with operations using what we're about to change */
- if(waserror()){
- qunlock(&s->in.ctlq);
- qunlock(&s->out.q);
- nexterror();
- }
- qlock(&s->in.ctlq);
- qlock(&s->out.q);
-
- switch(t){
- default:
- panic("sslwrite");
- case Qsecretin:
- setsecret(&s->in, a, n);
- goto out;
- case Qsecretout:
- setsecret(&s->out, a, n);
- goto out;
- case Qctl:
- break;
- }
-
- cb = parsecmd(a, n);
- if(waserror()){
- free(cb);
- nexterror();
- }
- ct = lookupcmd(cb, sslcmds, nelem(sslcmds));
- switch(ct->index){
- case Cfd:
- s->c = buftochan(cb->f[1]);
-
- /* default is clear (msg delimiters only) */
- s->state = Sclear;
- s->blocklen = 1;
- s->diglen = 0;
- s->maxpad = s->max = (1<<15) - s->diglen - 1;
- s->in.mid = 0;
- s->out.mid = 0;
- break;
- case Calg:
- if(cb->nf < 2)
- cmderror(cb, "no algorithms");
-
- s->blocklen = 1;
- s->diglen = 0;
-
- if(s->c == 0)
- error("must set fd before algorithm");
-
- s->state = Sclear;
- s->maxpad = s->max = (1<<15) - s->diglen - 1;
- if(strcmp(cb->f[1], "clear") == 0)
- break;
-
- if(s->in.secret && s->out.secret == 0)
- setsecret(&s->out, s->in.secret, s->in.slen);
- if(s->out.secret && s->in.secret == 0)
- setsecret(&s->in, s->out.secret, s->out.slen);
- if(s->in.secret == 0 || s->out.secret == 0)
- error("algorithm but no secret");
-
- s->hf = 0;
- s->encryptalg = Noencryption;
- s->blocklen = 1;
-
- for(i=1; i<cb->nf; i++){
- p = cb->f[i];
- if(parsehashalg(p, s) < 0)
- if(parseencryptalg(p, s) < 0)
- error("bad algorithm");
- }
-
- if(s->hf == 0 && s->encryptalg == Noencryption)
- error("bad algorithm");
-
- if(s->blocklen != 1){
- s->max = (1<<15) - s->diglen - 1;
- s->max -= s->max % s->blocklen;
- s->maxpad = (1<<14) - s->diglen - 1;
- s->maxpad -= s->maxpad % s->blocklen;
- } else
- s->maxpad = s->max = (1<<15) - s->diglen - 1;
- break;
- case Csin:
- p = cb->f[1];
- m = (strlen(p)*3)/2 + 1;
- x = secalloc(m);
- t = dec64(x, m, p, strlen(p));
- memset(p, 0, strlen(p));
- if(t <= 0){
- secfree(x);
- error(Ebadarg);
- }
- setsecret(&s->in, x, t);
- secfree(x);
- break;
- case Csout:
- p = cb->f[1];
- m = (strlen(p)*3)/2 + 1;
- x = secalloc(m);
- t = dec64(x, m, p, strlen(p));
- memset(p, 0, strlen(p));
- if(t <= 0){
- secfree(x);
- error(Ebadarg);
- }
- setsecret(&s->out, x, t);
- secfree(x);
- break;
- }
- poperror();
- free(cb);
-
-out:
- qunlock(&s->in.ctlq);
- qunlock(&s->out.q);
- poperror();
- return n;
-}
-
-static void
-sslinit(void)
-{
- struct Encalg *e;
- struct Hashalg *h;
- int n;
- char *cp;
-
- n = 1;
- for(e = encrypttab; e->name != nil; e++)
- n += strlen(e->name) + 1;
- cp = encalgs = smalloc(n);
- for(e = encrypttab;;){
- strcpy(cp, e->name);
- cp += strlen(e->name);
- e++;
- if(e->name == nil)
- break;
- *cp++ = ' ';
- }
- *cp = 0;
-
- n = 1;
- for(h = hashtab; h->name != nil; h++)
- n += strlen(h->name) + 1;
- cp = hashalgs = smalloc(n);
- for(h = hashtab;;){
- strcpy(cp, h->name);
- cp += strlen(h->name);
- h++;
- if(h->name == nil)
- break;
- *cp++ = ' ';
- }
- *cp = 0;
-}
-
-Dev ssldevtab = {
- 'D',
- "ssl",
-
- devreset,
- sslinit,
- devshutdown,
- sslattach,
- sslwalk,
- sslstat,
- sslopen,
- devcreate,
- sslclose,
- sslread,
- sslbread,
- sslwrite,
- sslbwrite,
- devremove,
- sslwstat,
-};
-
-static Block*
-encryptb(Dstate *s, Block *b, int offset)
-{
- uchar *p, *ep, *p2, *ip, *eip;
- DESstate *ds;
-
- switch(s->encryptalg){
- case DESECB:
- ds = s->out.state;
- ep = b->rp + BLEN(b);
- for(p = b->rp + offset; p < ep; p += 8)
- block_cipher(ds->expanded, p, 0);
- break;
- case DESCBC:
- ds = s->out.state;
- ep = b->rp + BLEN(b);
- for(p = b->rp + offset; p < ep; p += 8){
- p2 = p;
- ip = ds->ivec;
- for(eip = ip+8; ip < eip; )
- *p2++ ^= *ip++;
- block_cipher(ds->expanded, p, 0);
- memmove(ds->ivec, p, 8);
- }
- break;
- case RC4:
- rc4(s->out.state, b->rp + offset, BLEN(b) - offset);
- break;
- }
- return b;
-}
-
-static Block*
-decryptb(Dstate *s, Block *bin)
-{
- Block *b, **l;
- uchar *p, *ep, *tp, *ip, *eip;
- DESstate *ds;
- uchar tmp[8];
- int i;
-
- l = &bin;
- for(b = bin; b; b = b->next){
- /* make sure we have a multiple of s->blocklen */
- if(s->blocklen > 1){
- i = BLEN(b);
- if(i % s->blocklen){
- *l = b = pullupblock(b, i + s->blocklen - (i%s->blocklen));
- if(b == 0)
- error("ssl encrypted message too short");
- }
- }
- l = &b->next;
-
- /* decrypt */
- switch(s->encryptalg){
- case DESECB:
- ds = s->in.state;
- ep = b->rp + BLEN(b);
- for(p = b->rp; p < ep; p += 8)
- block_cipher(ds->expanded, p, 1);
- break;
- case DESCBC:
- ds = s->in.state;
- ep = b->rp + BLEN(b);
- for(p = b->rp; p < ep;){
- memmove(tmp, p, 8);
- block_cipher(ds->expanded, p, 1);
- tp = tmp;
- ip = ds->ivec;
- for(eip = ip+8; ip < eip; ){
- *p++ ^= *ip;
- *ip++ = *tp++;
- }
- }
- break;
- case RC4:
- rc4(s->in.state, b->rp, BLEN(b));
- break;
- }
- }
- return bin;
-}
-
-static Block*
-digestb(Dstate *s, Block *b, int offset)
-{
- uchar *p;
- DigestState ss;
- uchar msgid[4];
- ulong n, h;
- OneWay *w;
-
- w = &s->out;
-
- memset(&ss, 0, sizeof(ss));
- h = s->diglen + offset;
- n = BLEN(b) - h;
-
- /* hash secret + message */
- (*s->hf)(w->secret, w->slen, 0, &ss);
- (*s->hf)(b->rp + h, n, 0, &ss);
-
- /* hash message id */
- p = msgid;
- n = w->mid;
- *p++ = n>>24;
- *p++ = n>>16;
- *p++ = n>>8;
- *p = n;
- (*s->hf)(msgid, 4, b->rp + offset, &ss);
-
- return b;
-}
-
-static void
-checkdigestb(Dstate *s, Block *bin)
-{
- uchar *p;
- DigestState ss;
- uchar msgid[4];
- int n, h;
- OneWay *w;
- uchar digest[128];
- Block *b;
-
- w = &s->in;
-
- memset(&ss, 0, sizeof(ss));
-
- /* hash secret */
- (*s->hf)(w->secret, w->slen, 0, &ss);
-
- /* hash message */
- h = s->diglen;
- for(b = bin; b; b = b->next){
- n = BLEN(b) - h;
- if(n < 0)
- panic("checkdigestb");
- (*s->hf)(b->rp + h, n, 0, &ss);
- h = 0;
- }
-
- /* hash message id */
- p = msgid;
- n = w->mid;
- *p++ = n>>24;
- *p++ = n>>16;
- *p++ = n>>8;
- *p = n;
- (*s->hf)(msgid, 4, digest, &ss);
-
- if(tsmemcmp(digest, bin->rp, s->diglen) != 0)
- error("bad digest");
-}
-
-/* get channel associated with an fd */
-static Chan*
-buftochan(char *p)
-{
- Chan *c;
- int fd;
-
- if(p == 0)
- error(Ebadarg);
- fd = strtoul(p, 0, 0);
- if(fd < 0)
- error(Ebadarg);
- c = fdtochan(fd, ORDWR, 1, 1); /* error check and inc ref */
- if(devtab[c->type] == &ssldevtab){
- cclose(c);
- error("cannot ssl encrypt devssl files");
- }
- return c;
-}
-
-/* hand up a digest connection */
-static void
-sslhangup(Dstate *s)
-{
- Block *b;
-
- qlock(&s->in.q);
- for(b = s->processed; b; b = s->processed){
- s->processed = b->next;
- freeb(b);
- }
- if(s->unprocessed){
- freeb(s->unprocessed);
- s->unprocessed = 0;
- }
- s->state = Sincomplete;
- qunlock(&s->in.q);
-}
-
-static Dstate*
-dsclone(Chan *ch)
-{
- int i;
- Dstate *ret;
-
- if(waserror()) {
- unlock(&dslock);
- nexterror();
- }
- lock(&dslock);
- ret = nil;
- for(i=0; i<Maxdstate; i++){
- if(dstate[i] == nil){
- dsnew(ch, &dstate[i]);
- ret = dstate[i];
- break;
- }
- }
- unlock(&dslock);
- poperror();
- return ret;
-}
-
-static void
-dsnew(Chan *ch, Dstate **pp)
-{
- Dstate *s;
- int t;
-
- *pp = s = malloc(sizeof(*s));
- if(!s)
- error(Enomem);
- if(pp - dstate >= dshiwat)
- dshiwat++;
- memset(s, 0, sizeof(*s));
- s->state = Sincomplete;
- s->ref = 1;
- kstrdup(&s->user, up->user);
- s->perm = 0660;
- t = TYPE(ch->qid);
- if(t == Qclonus)
- t = Qctl;
- ch->qid.path = QID(pp - dstate, t);
- ch->qid.vers = 0;
-}
--- a/kern/devtab.c
+++ b/kern/devtab.c
@@ -7,16 +7,9 @@
extern Dev consdevtab;
extern Dev rootdevtab;
extern Dev pipedevtab;
-extern Dev ssldevtab;
-extern Dev tlsdevtab;
-extern Dev mousedevtab;
-extern Dev drawdevtab;
-extern Dev ipdevtab;
extern Dev fsdevtab;
extern Dev mntdevtab;
extern Dev lfddevtab;
-extern Dev audiodevtab;
-extern Dev kbddevtab;
extern Dev cmddevtab;
extern Dev envdevtab;
@@ -24,16 +17,9 @@
&rootdevtab,
&consdevtab,
&pipedevtab,
- &ssldevtab,
- &tlsdevtab,
- &mousedevtab,
- &drawdevtab,
- &ipdevtab,
&fsdevtab,
&mntdevtab,
&lfddevtab,
- &audiodevtab,
- &kbddevtab,
&cmddevtab,
&envdevtab,
0
--- a/kern/devtls.c
+++ /dev/null
@@ -1,2380 +1,0 @@
-/*
- * devtls - record layer for transport layer security 1.2 and secure sockets layer 3.0
- */
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-
-#include <libsec.h>
-
-typedef struct OneWay OneWay;
-typedef struct Secret Secret;
-typedef struct TlsRec TlsRec;
-typedef struct TlsErrs TlsErrs;
-
-enum {
- Statlen= 1024, /* max. length of status or stats message */
- /* buffer limits */
- MaxRecLen = 1<<14, /* max payload length of a record layer message */
- MaxCipherRecLen = MaxRecLen + 2048,
- RecHdrLen = 5,
- MaxMacLen = SHA2_256dlen,
-
- /* protocol versions we can accept */
- SSL3Version = 0x0300,
- TLS10Version = 0x0301,
- TLS11Version = 0x0302,
- TLS12Version = 0x0303,
- MinProtoVersion = 0x0300, /* limits on version we accept */
- MaxProtoVersion = 0x03ff,
-
- /* connection states */
- SHandshake = 1 << 0, /* doing handshake */
- SOpen = 1 << 1, /* application data can be sent */
- SRClose = 1 << 2, /* remote side has closed down */
- SLClose = 1 << 3, /* sent a close notify alert */
- SAlert = 1 << 5, /* sending or sent a fatal alert */
- SError = 1 << 6, /* some sort of error has occured */
- SClosed = 1 << 7, /* it is all over */
-
- /* record types */
- RChangeCipherSpec = 20,
- RAlert,
- RHandshake,
- RApplication,
-
- SSL2ClientHello = 1,
- HSSL2ClientHello = 9, /* local convention; see tlshand.c */
-
- /* alerts */
- ECloseNotify = 0,
- EUnexpectedMessage = 10,
- EBadRecordMac = 20,
- EDecryptionFailed = 21,
- ERecordOverflow = 22,
- EDecompressionFailure = 30,
- EHandshakeFailure = 40,
- ENoCertificate = 41,
- EBadCertificate = 42,
- EUnsupportedCertificate = 43,
- ECertificateRevoked = 44,
- ECertificateExpired = 45,
- ECertificateUnknown = 46,
- EIllegalParameter = 47,
- EUnknownCa = 48,
- EAccessDenied = 49,
- EDecodeError = 50,
- EDecryptError = 51,
- EExportRestriction = 60,
- EProtocolVersion = 70,
- EInsufficientSecurity = 71,
- EInternalError = 80,
- EUserCanceled = 90,
- ENoRenegotiation = 100,
- EUnrecognizedName = 112,
-
- EMAX = 256
-};
-
-struct Secret
-{
- char *encalg; /* name of encryption alg */
- char *hashalg; /* name of hash alg */
-
- int (*aead_enc)(Secret*, uchar*, int, uchar*, uchar*, int);
- int (*aead_dec)(Secret*, uchar*, int, uchar*, uchar*, int);
-
- int (*enc)(Secret*, uchar*, int);
- int (*dec)(Secret*, uchar*, int);
- int (*unpad)(uchar*, int, int);
- DigestState* (*mac)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
-
- int block; /* encryption block len, 0 if none */
- int maclen; /* # bytes of record mac / authentication tag */
- int recivlen; /* # bytes of record iv for AEAD ciphers */
- void *enckey;
- uchar mackey[MaxMacLen];
-};
-
-struct OneWay
-{
- QLock io; /* locks io access */
- QLock seclock; /* locks secret paramaters */
- u64int seq;
- Secret *sec; /* cipher in use */
- Secret *new; /* cipher waiting for enable */
-};
-
-struct TlsRec
-{
- Chan *c; /* io channel */
- int ref; /* serialized by tdlock for atomic destroy */
- int version; /* version of the protocol we are speaking */
- char verset; /* version has been set */
- char opened; /* opened command every issued? */
- char err[ERRMAX]; /* error message to return to handshake requests */
- vlong handin; /* bytes communicated by the record layer */
- vlong handout;
- vlong datain;
- vlong dataout;
-
- Lock statelk;
- int state;
- int debug;
-
- /*
- * function to genrate authenticated data blob for different
- * protocol versions
- */
- int (*packAAD)(u64int, uchar*, uchar*);
-
- /* input side -- protected by in.io */
- OneWay in;
- Block *processed; /* next bunch of application data */
- Block *unprocessed; /* data read from c but not parsed into records */
-
- /* handshake queue */
- Lock hqlock; /* protects hqref, alloc & free of handq, hprocessed */
- int hqref;
- Queue *handq; /* queue of handshake messages */
- Block *hprocessed; /* remainder of last block read from handq */
- QLock hqread; /* protects reads for hprocessed, handq */
-
- /* output side */
- OneWay out;
-
- /* protections */
- char *user;
- int perm;
-};
-
-struct TlsErrs{
- int err;
- int sslerr;
- int tlserr;
- int fatal;
- char *msg;
-};
-
-static TlsErrs tlserrs[] = {
- {ECloseNotify, ECloseNotify, ECloseNotify, 0, "close notify"},
- {EUnexpectedMessage, EUnexpectedMessage, EUnexpectedMessage, 1, "unexpected message"},
- {EBadRecordMac, EBadRecordMac, EBadRecordMac, 1, "bad record mac"},
- {EDecryptionFailed, EIllegalParameter, EDecryptionFailed, 1, "decryption failed"},
- {ERecordOverflow, EIllegalParameter, ERecordOverflow, 1, "record too long"},
- {EDecompressionFailure, EDecompressionFailure, EDecompressionFailure, 1, "decompression failed"},
- {EHandshakeFailure, EHandshakeFailure, EHandshakeFailure, 1, "could not negotiate acceptable security parameters"},
- {ENoCertificate, ENoCertificate, ECertificateUnknown, 1, "no appropriate certificate available"},
- {EBadCertificate, EBadCertificate, EBadCertificate, 1, "corrupted or invalid certificate"},
- {EUnsupportedCertificate, EUnsupportedCertificate, EUnsupportedCertificate, 1, "unsupported certificate type"},
- {ECertificateRevoked, ECertificateRevoked, ECertificateRevoked, 1, "revoked certificate"},
- {ECertificateExpired, ECertificateExpired, ECertificateExpired, 1, "expired certificate"},
- {ECertificateUnknown, ECertificateUnknown, ECertificateUnknown, 1, "unacceptable certificate"},
- {EIllegalParameter, EIllegalParameter, EIllegalParameter, 1, "illegal parameter"},
- {EUnknownCa, EHandshakeFailure, EUnknownCa, 1, "unknown certificate authority"},
- {EAccessDenied, EHandshakeFailure, EAccessDenied, 1, "access denied"},
- {EDecodeError, EIllegalParameter, EDecodeError, 1, "error decoding message"},
- {EDecryptError, EIllegalParameter, EDecryptError, 1, "error decrypting message"},
- {EExportRestriction, EHandshakeFailure, EExportRestriction, 1, "export restriction violated"},
- {EProtocolVersion, EIllegalParameter, EProtocolVersion, 1, "protocol version not supported"},
- {EInsufficientSecurity, EHandshakeFailure, EInsufficientSecurity, 1, "stronger security routines required"},
- {EInternalError, EHandshakeFailure, EInternalError, 1, "internal error"},
- {EUserCanceled, ECloseNotify, EUserCanceled, 0, "handshake canceled by user"},
- {ENoRenegotiation, EUnexpectedMessage, ENoRenegotiation, 0, "no renegotiation"},
-};
-
-enum
-{
- /* max. open tls connections */
- MaxTlsDevs = 1024
-};
-
-static Lock tdlock;
-static int tdhiwat;
-static int maxtlsdevs = 128;
-static TlsRec **tlsdevs;
-static char **trnames;
-static char *encalgs;
-static char *hashalgs;
-
-enum{
- Qtopdir = 1, /* top level directory */
- Qprotodir,
- Qclonus,
- Qencalgs,
- Qhashalgs,
- Qconvdir, /* directory for a conversation */
- Qdata,
- Qctl,
- Qhand,
- Qstatus,
- Qstats,
-};
-
-#define TYPE(x) ((x).path & 0xf)
-#define CONV(x) (((x).path >> 5)&(MaxTlsDevs-1))
-#define QID(c, y) (((c)<<5) | (y))
-
-static void checkstate(TlsRec *, int, int);
-static void ensure(TlsRec*, Block**, int);
-static void consume(Block**, uchar*, int);
-static Chan* buftochan(char*);
-static void tlshangup(TlsRec*);
-static void tlsError(TlsRec*, char *);
-static void alertHand(TlsRec*, char *);
-static TlsRec *newtls(Chan *c);
-static TlsRec *mktlsrec(void);
-static DigestState*sslmac_md5(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s);
-static DigestState*sslmac_sha1(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s);
-static DigestState*nomac(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s);
-static int sslPackAAD(u64int, uchar*, uchar*);
-static int tlsPackAAD(u64int, uchar*, uchar*);
-static void packMac(Secret*, uchar*, int, uchar*, int, uchar*);
-static void put64(uchar *p, u64int);
-static void put32(uchar *p, u32int);
-static void put24(uchar *p, int);
-static void put16(uchar *p, int);
-static int get16(uchar *p);
-static void tlsSetState(TlsRec *tr, int new, int old);
-static void rcvAlert(TlsRec *tr, int err);
-static void sendAlert(TlsRec *tr, int err);
-static void rcvError(TlsRec *tr, int err, char *msg, ...);
-static int rc4enc(Secret *sec, uchar *buf, int n);
-static int des3enc(Secret *sec, uchar *buf, int n);
-static int des3dec(Secret *sec, uchar *buf, int n);
-static int aesenc(Secret *sec, uchar *buf, int n);
-static int aesdec(Secret *sec, uchar *buf, int n);
-static int ccpoly_aead_enc(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data, int len);
-static int ccpoly_aead_dec(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data, int len);
-static int aesgcm_aead_enc(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data, int len);
-static int aesgcm_aead_dec(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data, int len);
-static int noenc(Secret *sec, uchar *buf, int n);
-static int sslunpad(uchar *buf, int n, int block);
-static int tlsunpad(uchar *buf, int n, int block);
-static void freeSec(Secret *sec);
-static char *tlsstate(int s);
-static void pdump(int, void*, char*);
-
-static char *tlsnames[] = {
-[Qclonus] "clone",
-[Qencalgs] "encalgs",
-[Qhashalgs] "hashalgs",
-[Qdata] "data",
-[Qctl] "ctl",
-[Qhand] "hand",
-[Qstatus] "status",
-[Qstats] "stats",
-};
-
-static int convdir[] = { Qctl, Qdata, Qhand, Qstatus, Qstats };
-
-static int
-tlsgen(Chan *c, char *unused1, Dirtab *unused2, int unused3, int s, Dir *dp)
-{
- Qid q;
- TlsRec *tr;
- char *name, *nm;
- int perm, t;
-
- q.vers = 0;
- q.type = QTFILE;
-
- t = TYPE(c->qid);
- switch(t) {
- case Qtopdir:
- if(s == DEVDOTDOT){
- q.path = QID(0, Qtopdir);
- q.type = QTDIR;
- devdir(c, q, "#a", 0, eve, 0555, dp);
- return 1;
- }
- if(s > 0)
- return -1;
- q.path = QID(0, Qprotodir);
- q.type = QTDIR;
- devdir(c, q, "tls", 0, eve, 0555, dp);
- return 1;
- case Qprotodir:
- if(s == DEVDOTDOT){
- q.path = QID(0, Qtopdir);
- q.type = QTDIR;
- devdir(c, q, ".", 0, eve, 0555, dp);
- return 1;
- }
- if(s < 3){
- switch(s) {
- default:
- return -1;
- case 0:
- q.path = QID(0, Qclonus);
- break;
- case 1:
- q.path = QID(0, Qencalgs);
- break;
- case 2:
- q.path = QID(0, Qhashalgs);
- break;
- }
- perm = 0444;
- if(TYPE(q) == Qclonus)
- perm = 0555;
- devdir(c, q, tlsnames[TYPE(q)], 0, eve, perm, dp);
- return 1;
- }
- s -= 3;
- if(s >= tdhiwat)
- return -1;
- q.path = QID(s, Qconvdir);
- q.type = QTDIR;
- lock(&tdlock);
- tr = tlsdevs[s];
- if(tr != nil)
- nm = tr->user;
- else
- nm = eve;
- if((name = trnames[s]) == nil){
- name = trnames[s] = smalloc(16);
- sprint(name, "%d", s);
- }
- devdir(c, q, name, 0, nm, 0555, dp);
- unlock(&tdlock);
- return 1;
- case Qconvdir:
- if(s == DEVDOTDOT){
- q.path = QID(0, Qprotodir);
- q.type = QTDIR;
- devdir(c, q, "tls", 0, eve, 0555, dp);
- return 1;
- }
- if(s < 0 || s >= nelem(convdir))
- return -1;
- lock(&tdlock);
- tr = tlsdevs[CONV(c->qid)];
- if(tr != nil){
- nm = tr->user;
- perm = tr->perm;
- }else{
- perm = 0;
- nm = eve;
- }
- t = convdir[s];
- if(t == Qstatus || t == Qstats)
- perm &= 0444;
- q.path = QID(CONV(c->qid), t);
- devdir(c, q, tlsnames[t], 0, nm, perm, dp);
- unlock(&tdlock);
- return 1;
- case Qclonus:
- case Qencalgs:
- case Qhashalgs:
- perm = 0444;
- if(t == Qclonus)
- perm = 0555;
- devdir(c, c->qid, tlsnames[t], 0, eve, perm, dp);
- return 1;
- default:
- lock(&tdlock);
- tr = tlsdevs[CONV(c->qid)];
- if(tr != nil){
- nm = tr->user;
- perm = tr->perm;
- }else{
- perm = 0;
- nm = eve;
- }
- if(t == Qstatus || t == Qstats)
- perm &= 0444;
- devdir(c, c->qid, tlsnames[t], 0, nm, perm, dp);
- unlock(&tdlock);
- return 1;
- }
-}
-
-static Chan*
-tlsattach(char *spec)
-{
- Chan *c;
-
- c = devattach('a', spec);
- c->qid.path = QID(0, Qtopdir);
- c->qid.type = QTDIR;
- c->qid.vers = 0;
- return c;
-}
-
-static Walkqid*
-tlswalk(Chan *c, Chan *nc, char **name, int nname)
-{
- return devwalk(c, nc, name, nname, nil, 0, tlsgen);
-}
-
-static int
-tlsstat(Chan *c, uchar *db, int n)
-{
- return devstat(c, db, n, nil, 0, tlsgen);
-}
-
-static Chan*
-tlsopen(Chan *c, int omode)
-{
- TlsRec *tr, **pp;
- int t;
-
- t = TYPE(c->qid);
- switch(t) {
- default:
- panic("tlsopen");
- case Qtopdir:
- case Qprotodir:
- case Qconvdir:
- if(omode != OREAD)
- error(Eperm);
- break;
- case Qclonus:
- tr = newtls(c);
- if(tr == nil)
- error(Enodev);
- break;
- case Qctl:
- case Qdata:
- case Qhand:
- case Qstatus:
- case Qstats:
- if((t == Qstatus || t == Qstats) && omode != OREAD)
- error(Eperm);
- if(waserror()) {
- unlock(&tdlock);
- nexterror();
- }
- lock(&tdlock);
- pp = &tlsdevs[CONV(c->qid)];
- tr = *pp;
- if(tr == nil)
- error("must open connection using clone");
- devpermcheck(tr->user, tr->perm, omode);
- if(t == Qhand){
- if(waserror()){
- unlock(&tr->hqlock);
- nexterror();
- }
- lock(&tr->hqlock);
- if(tr->handq != nil)
- error(Einuse);
- tr->handq = qopen(2 * MaxCipherRecLen, 0, nil, nil);
- if(tr->handq == nil)
- error("cannot allocate handshake queue");
- tr->hqref = 1;
- unlock(&tr->hqlock);
- poperror();
- }
- tr->ref++;
- unlock(&tdlock);
- poperror();
- break;
- case Qencalgs:
- case Qhashalgs:
- if(omode != OREAD)
- error(Eperm);
- break;
- }
- c->mode = openmode(omode);
- c->flag |= COPEN;
- c->offset = 0;
- switch(t){
- case Qdata:
- c->iounit = qiomaxatomic;
- break;
- case Qhand:
- c->iounit = MaxRecLen;
- break;
- default:
- c->iounit = 0;
- break;
- }
- return c;
-}
-
-static int
-tlswstat(Chan *c, uchar *dp, int n)
-{
- Dir *d;
- TlsRec *tr;
- int rv;
-
- d = nil;
- if(waserror()){
- free(d);
- unlock(&tdlock);
- nexterror();
- }
-
- lock(&tdlock);
- tr = tlsdevs[CONV(c->qid)];
- if(tr == nil)
- error(Ebadusefd);
- if(strcmp(tr->user, up->user) != 0)
- error(Eperm);
-
- d = smalloc(n + sizeof *d);
- rv = convM2D(dp, n, &d[0], (char*) &d[1]);
- if(rv == 0)
- error(Eshortstat);
- if(!emptystr(d->uid))
- kstrdup(&tr->user, d->uid);
- if(d->mode != -1)
- tr->perm = d->mode;
-
- free(d);
- poperror();
- unlock(&tdlock);
-
- return rv;
-}
-
-static void
-dechandq(TlsRec *tr)
-{
- lock(&tr->hqlock);
- if(--tr->hqref == 0){
- if(tr->handq != nil){
- qfree(tr->handq);
- tr->handq = nil;
- }
- if(tr->hprocessed != nil){
- freeb(tr->hprocessed);
- tr->hprocessed = nil;
- }
- }
- unlock(&tr->hqlock);
-}
-
-static void
-tlsclose(Chan *c)
-{
- TlsRec *tr;
- int t;
-
- t = TYPE(c->qid);
- switch(t) {
- case Qctl:
- case Qdata:
- case Qhand:
- case Qstatus:
- case Qstats:
- if((c->flag & COPEN) == 0)
- break;
-
- tr = tlsdevs[CONV(c->qid)];
- if(tr == nil)
- break;
-
- if(t == Qhand)
- dechandq(tr);
-
- lock(&tdlock);
- if(--tr->ref > 0) {
- unlock(&tdlock);
- return;
- }
- tlsdevs[CONV(c->qid)] = nil;
- unlock(&tdlock);
-
- if(tr->c != nil && !waserror()){
- checkstate(tr, 0, SOpen|SHandshake|SRClose);
- sendAlert(tr, ECloseNotify);
- poperror();
- }
- tlshangup(tr);
- if(tr->c != nil)
- cclose(tr->c);
- freeSec(tr->in.sec);
- freeSec(tr->in.new);
- freeSec(tr->out.sec);
- freeSec(tr->out.new);
- free(tr->user);
- free(tr);
- break;
- }
-}
-
-/*
- * make sure we have at least 'n' bytes in list 'l'
- */
-static void
-ensure(TlsRec *s, Block **l, int n)
-{
- int sofar, i;
- Block *b, *bl;
-
- sofar = 0;
- for(b = *l; b; b = b->next){
- sofar += BLEN(b);
- if(sofar >= n)
- return;
- l = &b->next;
- }
-
- while(sofar < n){
- bl = devtab[s->c->type]->bread(s->c, MaxCipherRecLen + RecHdrLen, 0);
- if(bl == 0)
- error(Ehungup);
- *l = bl;
- i = 0;
- for(b = bl; b; b = b->next){
- i += BLEN(b);
- l = &b->next;
- }
- if(i == 0)
- error(Ehungup);
- sofar += i;
- }
-if(s->debug) pprint("ensure read %d\n", sofar);
-}
-
-/*
- * copy 'n' bytes from 'l' into 'p' and free
- * the bytes in 'l'
- */
-static void
-consume(Block **l, uchar *p, int n)
-{
- Block *b;
- int i;
-
- for(; *l && n > 0; n -= i){
- b = *l;
- i = BLEN(b);
- if(i > n)
- i = n;
- memmove(p, b->rp, i);
- b->rp += i;
- p += i;
- if(BLEN(b) < 0)
- panic("consume");
- if(BLEN(b))
- break;
- *l = b->next;
- freeb(b);
- }
-}
-
-/*
- * give back n bytes
- */
-static void
-regurgitate(TlsRec *s, uchar *p, int n)
-{
- Block *b;
-
- if(n <= 0)
- return;
- b = s->unprocessed;
- if(s->unprocessed == nil || b->rp - b->base < n) {
- b = allocb(n);
- memmove(b->wp, p, n);
- b->wp += n;
- b->next = s->unprocessed;
- s->unprocessed = b;
- } else {
- b->rp -= n;
- memmove(b->rp, p, n);
- }
-}
-
-/*
- * remove at most n bytes from the queue
- */
-static Block*
-qgrab(Block **l, int n)
-{
- Block *bb, *b;
- int i;
-
- b = *l;
- if(BLEN(b) == n){
- *l = b->next;
- b->next = nil;
- return b;
- }
-
- i = 0;
- for(bb = b; bb != nil && i < n; bb = bb->next)
- i += BLEN(bb);
- if(i > n)
- i = n;
-
- bb = allocb(i);
- consume(l, bb->wp, i);
- bb->wp += i;
- return bb;
-}
-
-static void
-tlsclosed(TlsRec *tr, int new)
-{
- lock(&tr->statelk);
- if(tr->state == SOpen || tr->state == SHandshake)
- tr->state = new;
- else if((new | tr->state) == (SRClose|SLClose))
- tr->state = SClosed;
- unlock(&tr->statelk);
- alertHand(tr, "close notify");
-}
-
-/*
- * read and process one tls record layer message
- * must be called with tr->in.io held
- * We can't let Eintrs lose data, since doing so will get
- * us out of sync with the sender and break the reliablity
- * of the channel. Eintr only happens during the reads in
- * consume. Therefore we put back any bytes consumed before
- * the last call to ensure.
- */
-static void
-tlsrecread(TlsRec *tr)
-{
- OneWay *volatile in;
- Block *volatile b;
- uchar *p, aad[8+RecHdrLen], header[RecHdrLen], hmac[MaxMacLen];
- int volatile nconsumed;
- int len, type, ver, unpad_len, aadlen, ivlen;
- Secret *sec;
-
- nconsumed = 0;
- if(waserror()){
- if(strcmp(up->errstr, Eintr) == 0 && !waserror()){
- regurgitate(tr, header, nconsumed);
- poperror();
- }else
- tlsError(tr, "channel error");
- nexterror();
- }
- ensure(tr, &tr->unprocessed, RecHdrLen);
- consume(&tr->unprocessed, header, RecHdrLen);
-if(tr->debug)pprint("consumed %d header\n", RecHdrLen);
- nconsumed = RecHdrLen;
-
- if((tr->handin == 0) && (header[0] & 0x80)){
- /* Cope with an SSL3 ClientHello expressed in SSL2 record format.
- This is sent by some clients that we must interoperate
- with, such as Java's JSSE and Microsoft's Internet Explorer. */
- len = (get16(header) & ~0x8000) - 3;
- type = header[2];
- ver = get16(header + 3);
- if(type != SSL2ClientHello || len < 22)
- rcvError(tr, EProtocolVersion, "invalid initial SSL2-like message");
- }else{ /* normal SSL3 record format */
- type = header[0];
- ver = get16(header+1);
- len = get16(header+3);
- }
- if(ver != tr->version && (tr->verset || ver < MinProtoVersion || ver > MaxProtoVersion))
- rcvError(tr, EProtocolVersion, "devtls expected ver=%x%s, saw (len=%d) type=%x ver=%x '%.12s'",
- tr->version, tr->verset?"/set":"", len, type, ver, (char*)header);
- if(len > MaxCipherRecLen || len <= 0)
- rcvError(tr, ERecordOverflow, "bad record message length %d", len);
- ensure(tr, &tr->unprocessed, len);
- nconsumed = 0;
- poperror();
-
- /*
- * If an Eintr happens after this, we'll get out of sync.
- * Make sure nothing we call can sleep.
- * Errors are ok, as they kill the connection.
- * Luckily, allocb won't sleep, it'll just error out.
- */
- b = nil;
- if(waserror()){
- if(b != nil)
- freeb(b);
- tlsError(tr, "channel error");
- nexterror();
- }
- b = qgrab(&tr->unprocessed, len);
-if(tr->debug) pprint("consumed unprocessed %d\n", len);
-
- in = &tr->in;
- if(waserror()){
- qunlock(&in->seclock);
- nexterror();
- }
- qlock(&in->seclock);
- p = b->rp;
- sec = in->sec;
- if(sec != nil) {
- /* to avoid Canvel-Hiltgen-Vaudenay-Vuagnoux attack, all errors here
- should look alike, including timing of the response. */
- if(sec->aead_dec != nil)
- unpad_len = len;
- else {
- unpad_len = (*sec->dec)(sec, p, len);
-if(tr->debug) pprint("decrypted %d\n", unpad_len);
-if(tr->debug) pdump(unpad_len, p, "decrypted:");
- }
-
- ivlen = sec->recivlen;
- if(tr->version >= TLS11Version){
- if(ivlen == 0)
- ivlen = sec->block;
- }
- len -= ivlen;
- if(len < 0)
- rcvError(tr, EDecodeError, "runt record message");
- unpad_len -= ivlen;
- p += ivlen;
-
- if(unpad_len >= sec->maclen)
- len = unpad_len - sec->maclen;
-
- /* update length */
- put16(header+3, len);
- aadlen = (*tr->packAAD)(in->seq++, header, aad);
- if(sec->aead_dec != nil) {
- len = (*sec->aead_dec)(sec, aad, aadlen, p - ivlen, p, unpad_len);
- if(len < 0)
- rcvError(tr, EBadRecordMac, "record mac mismatch");
- } else {
- packMac(sec, aad, aadlen, p, len, hmac);
- if(unpad_len < sec->maclen)
- rcvError(tr, EBadRecordMac, "short record mac");
- if(tsmemcmp(hmac, p + len, sec->maclen) != 0)
- rcvError(tr, EBadRecordMac, "record mac mismatch");
- }
- b->rp = p;
- b->wp = p+len;
- }
- qunlock(&in->seclock);
- poperror();
- if(len < 0)
- rcvError(tr, EDecodeError, "runt record message");
-
- switch(type) {
- default:
- rcvError(tr, EIllegalParameter, "invalid record message %#x", type);
- break;
- case RChangeCipherSpec:
- if(len != 1 || p[0] != 1)
- rcvError(tr, EDecodeError, "invalid change cipher spec");
- qlock(&in->seclock);
- if(in->new == nil){
- qunlock(&in->seclock);
- rcvError(tr, EUnexpectedMessage, "unexpected change cipher spec");
- }
- freeSec(in->sec);
- in->sec = in->new;
- in->new = nil;
- in->seq = 0;
- qunlock(&in->seclock);
- break;
- case RAlert:
- if(len != 2)
- rcvError(tr, EDecodeError, "invalid alert");
- if(p[0] == 2)
- rcvAlert(tr, p[1]);
- if(p[0] != 1)
- rcvError(tr, EIllegalParameter, "invalid alert fatal code");
-
- /*
- * propagate non-fatal alerts to handshaker
- */
- switch(p[1]){
- case ECloseNotify:
- tlsclosed(tr, SRClose);
- if(tr->opened)
- error("tls hungup");
- error("close notify");
- break;
- case ENoRenegotiation:
- alertHand(tr, "no renegotiation");
- break;
- case EUserCanceled:
- alertHand(tr, "handshake canceled by user");
- break;
- case EUnrecognizedName:
- /* happens in response to SNI, can be ignored. */
- break;
- default:
- rcvError(tr, EIllegalParameter, "invalid alert code");
- }
- break;
- case RHandshake:
- /*
- * don't worry about dropping the block
- * qbwrite always queues even if flow controlled and interrupted.
- *
- * if there isn't any handshaker, ignore the request,
- * but notify the other side we are doing so.
- */
- lock(&tr->hqlock);
- if(tr->handq != nil){
- tr->hqref++;
- unlock(&tr->hqlock);
- if(waserror()){
- dechandq(tr);
- nexterror();
- }
- b = padblock(b, 1);
- *b->rp = RHandshake;
- qbwrite(tr->handq, b);
- b = nil;
- poperror();
- dechandq(tr);
- }else{
- unlock(&tr->hqlock);
- if(tr->verset && tr->version != SSL3Version && !waserror()){
- sendAlert(tr, ENoRenegotiation);
- poperror();
- }
- }
- break;
- case SSL2ClientHello:
- lock(&tr->hqlock);
- if(tr->handq != nil){
- tr->hqref++;
- unlock(&tr->hqlock);
- if(waserror()){
- dechandq(tr);
- nexterror();
- }
- /* Pass the SSL2 format data, so that the handshake code can compute
- the correct checksums. HSSL2ClientHello = HandshakeType 9 is
- unused in RFC2246. */
- b = padblock(b, 8);
- b->rp[0] = RHandshake;
- b->rp[1] = HSSL2ClientHello;
- put24(&b->rp[2], len+3);
- b->rp[5] = SSL2ClientHello;
- put16(&b->rp[6], ver);
- qbwrite(tr->handq, b);
- b = nil;
- poperror();
- dechandq(tr);
- }else{
- unlock(&tr->hqlock);
- if(tr->verset && tr->version != SSL3Version && !waserror()){
- sendAlert(tr, ENoRenegotiation);
- poperror();
- }
- }
- break;
- case RApplication:
- if(!tr->opened)
- rcvError(tr, EUnexpectedMessage, "application message received before handshake completed");
- if(BLEN(b) > 0){
- tr->processed = b;
- b = nil;
- }
- break;
- }
- if(b != nil)
- freeb(b);
- poperror();
-}
-
-/*
- * got a fatal alert message
- */
-static void
-rcvAlert(TlsRec *tr, int err)
-{
- char *s;
- int i;
-
- s = "unknown error";
- for(i=0; i < nelem(tlserrs); i++){
- if(tlserrs[i].err == err){
- s = tlserrs[i].msg;
- break;
- }
- }
-if(tr->debug) pprint("rcvAlert: %s\n", s);
-
- tlsError(tr, s);
- if(!tr->opened)
- error(s);
- error("tls error");
-}
-
-/*
- * found an error while decoding the input stream
- */
-static void
-rcvError(TlsRec *tr, int err, char *fmt, ...)
-{
- char msg[ERRMAX];
- va_list arg;
-
- va_start(arg, fmt);
- vseprint(msg, msg+sizeof(msg), fmt, arg);
- va_end(arg);
-if(tr->debug) pprint("rcvError: %s\n", msg);
-
- sendAlert(tr, err);
-
- if(!tr->opened)
- error(msg);
- error("tls error");
-}
-
-/*
- * make sure the next hand operation returns with a 'msg' error
- */
-static void
-alertHand(TlsRec *tr, char *msg)
-{
- Block *b;
- int n;
-
- lock(&tr->hqlock);
- if(tr->handq == nil){
- unlock(&tr->hqlock);
- return;
- }
- tr->hqref++;
- unlock(&tr->hqlock);
-
- n = strlen(msg);
- if(waserror()){
- dechandq(tr);
- nexterror();
- }
- b = allocb(n + 2);
- *b->wp++ = RAlert;
- memmove(b->wp, msg, n + 1);
- b->wp += n + 1;
-
- qbwrite(tr->handq, b);
-
- poperror();
- dechandq(tr);
-}
-
-static void
-checkstate(TlsRec *tr, int ishand, int ok)
-{
- int state;
-
- lock(&tr->statelk);
- state = tr->state;
- unlock(&tr->statelk);
- if(state & ok)
- return;
- switch(state){
- case SHandshake:
- case SOpen:
- break;
- case SError:
- case SAlert:
- if(ishand)
- error(tr->err);
- error("tls error");
- case SRClose:
- case SLClose:
- case SClosed:
- error("tls hungup");
- }
- error("tls improperly configured");
-}
-
-static Block*
-tlsbread(Chan *c, long n, ulong offset)
-{
- int ty;
- Block *b;
- TlsRec *volatile tr;
-
- ty = TYPE(c->qid);
- switch(ty) {
- default:
- return devbread(c, n, offset);
- case Qhand:
- case Qdata:
- break;
- }
-
- tr = tlsdevs[CONV(c->qid)];
- if(tr == nil)
- panic("tlsbread");
-
- if(waserror()){
- qunlock(&tr->in.io);
- nexterror();
- }
- qlock(&tr->in.io);
- if(ty == Qdata){
- checkstate(tr, 0, SOpen);
- while(tr->processed == nil)
- tlsrecread(tr);
-
- /* return at most what was asked for */
- b = qgrab(&tr->processed, n);
-if(tr->debug) pprint("consumed processed %zd\n", BLEN(b));
-if(tr->debug) pdump(BLEN(b), b->rp, "consumed:");
- qunlock(&tr->in.io);
- poperror();
- tr->datain += BLEN(b);
- }else{
- checkstate(tr, 1, SOpen|SHandshake|SLClose);
-
- /*
- * it's ok to look at state without the lock
- * since it only protects reading records,
- * and we have that tr->in.io held.
- */
- while(!tr->opened && tr->hprocessed == nil && !qcanread(tr->handq))
- tlsrecread(tr);
-
- qunlock(&tr->in.io);
- poperror();
-
- if(waserror()){
- qunlock(&tr->hqread);
- nexterror();
- }
- qlock(&tr->hqread);
- if(tr->hprocessed == nil){
- b = qbread(tr->handq, MaxRecLen + 1);
- if(*b->rp++ == RAlert){
- kstrcpy(up->errstr, (char*)b->rp, ERRMAX);
- freeb(b);
- nexterror();
- }
- tr->hprocessed = b;
- }
- b = qgrab(&tr->hprocessed, n);
- poperror();
- qunlock(&tr->hqread);
- tr->handin += BLEN(b);
- }
-
- return b;
-}
-
-static long
-tlsread(Chan *c, void *a, long n, vlong off)
-{
- Block *volatile b;
- Block *nb;
- uchar *va;
- int i, ty;
- char *buf, *s, *e;
- ulong offset = off;
- TlsRec * tr;
-
- if(c->qid.type & QTDIR)
- return devdirread(c, a, n, 0, 0, tlsgen);
-
- tr = tlsdevs[CONV(c->qid)];
- ty = TYPE(c->qid);
- switch(ty) {
- default:
- error(Ebadusefd);
- case Qstatus:
- buf = smalloc(Statlen);
- qlock(&tr->in.seclock);
- qlock(&tr->out.seclock);
- s = buf;
- e = buf + Statlen;
- s = seprint(s, e, "State: %s\n", tlsstate(tr->state));
- s = seprint(s, e, "Version: %#x\n", tr->version);
- if(tr->in.sec != nil)
- s = seprint(s, e, "EncIn: %s\nHashIn: %s\n", tr->in.sec->encalg, tr->in.sec->hashalg);
- if(tr->in.new != nil)
- s = seprint(s, e, "NewEncIn: %s\nNewHashIn: %s\n", tr->in.new->encalg, tr->in.new->hashalg);
- if(tr->out.sec != nil)
- s = seprint(s, e, "EncOut: %s\nHashOut: %s\n", tr->out.sec->encalg, tr->out.sec->hashalg);
- if(tr->out.new != nil)
- s = seprint(s, e, "NewEncOut: %s\nNewHashOut: %s\n", tr->out.new->encalg, tr->out.new->hashalg);
- if(tr->c != nil)
- seprint(s, e, "Chan: %s\n", chanpath(tr->c));
- qunlock(&tr->in.seclock);
- qunlock(&tr->out.seclock);
- n = readstr(offset, a, n, buf);
- free(buf);
- return n;
- case Qstats:
- buf = smalloc(Statlen);
- s = buf;
- e = buf + Statlen;
- s = seprint(s, e, "DataIn: %lld\n", tr->datain);
- s = seprint(s, e, "DataOut: %lld\n", tr->dataout);
- s = seprint(s, e, "HandIn: %lld\n", tr->handin);
- seprint(s, e, "HandOut: %lld\n", tr->handout);
- n = readstr(offset, a, n, buf);
- free(buf);
- return n;
- case Qctl:
- buf = smalloc(Statlen);
- snprint(buf, Statlen, "%llud", CONV(c->qid));
- n = readstr(offset, a, n, buf);
- free(buf);
- return n;
- case Qdata:
- case Qhand:
- b = tlsbread(c, n, offset);
- break;
- case Qencalgs:
- return readstr(offset, a, n, encalgs);
- case Qhashalgs:
- return readstr(offset, a, n, hashalgs);
- }
-
- if(waserror()){
- freeblist(b);
- nexterror();
- }
-
- n = 0;
- va = a;
- for(nb = b; nb; nb = nb->next){
- i = BLEN(nb);
- memmove(va+n, nb->rp, i);
- n += i;
- }
-
- freeblist(b);
- poperror();
-
- return n;
-}
-
-/*
- * write a block in tls records
- */
-static void
-tlsrecwrite(TlsRec *tr, int type, Block *b)
-{
- Block *volatile bb;
- Block *nb;
- uchar *p, aad[8+RecHdrLen];
- OneWay *volatile out;
- int n, ivlen, maclen, aadlen, pad, ok;
- Secret *sec;
-
- out = &tr->out;
- bb = b;
- if(waserror()){
- qunlock(&out->io);
- if(bb != nil)
- freeb(bb);
- nexterror();
- }
- qlock(&out->io);
-if(tr->debug)pprint("send %zd\n", BLEN(b));
-if(tr->debug)pdump(BLEN(b), b->rp, "sent:");
-
-
- if(type == RApplication)
- checkstate(tr, 0, SOpen);
-
- ok = SHandshake|SOpen|SRClose;
- if(type == RAlert)
- ok |= SAlert;
- while(bb != nil){
- checkstate(tr, type != RApplication, ok);
-
- /*
- * get at most one maximal record's input,
- * with padding on the front for header and
- * back for mac and maximal block padding.
- */
- if(waserror()){
- qunlock(&out->seclock);
- nexterror();
- }
- qlock(&out->seclock);
- maclen = 0;
- pad = 0;
- ivlen = 0;
- sec = out->sec;
- if(sec != nil){
- maclen = sec->maclen;
- pad = maclen + sec->block;
- ivlen = sec->recivlen;
- if(tr->version >= TLS11Version){
- if(ivlen == 0)
- ivlen = sec->block;
- }
- }
- n = BLEN(bb);
- if(n > MaxRecLen){
- n = MaxRecLen;
- nb = allocb(RecHdrLen + ivlen + n + pad);
- memmove(nb->wp + RecHdrLen + ivlen, bb->rp, n);
- bb->rp += n;
- }else{
- /*
- * carefully reuse bb so it will get freed if we're out of memory
- */
- bb = padblock(bb, RecHdrLen + ivlen);
- if(pad)
- nb = padblock(bb, -pad);
- else
- nb = bb;
- bb = nil;
- }
-
- p = nb->rp;
- p[0] = type;
- put16(p+1, tr->version);
- put16(p+3, n);
-
- if(sec != nil){
- aadlen = (*tr->packAAD)(out->seq++, p, aad);
- if(sec->aead_enc != nil)
- n = (*sec->aead_enc)(sec, aad, aadlen, p + RecHdrLen, p + RecHdrLen + ivlen, n) + ivlen;
- else {
- if(ivlen > 0)
- prng(p + RecHdrLen, ivlen);
- packMac(sec, aad, aadlen, p + RecHdrLen + ivlen, n, p + RecHdrLen + ivlen + n);
- n = (*sec->enc)(sec, p + RecHdrLen, ivlen + n + maclen);
- }
- nb->wp = p + RecHdrLen + n;
-
- /* update length */
- put16(p+3, n);
- }
- if(type == RChangeCipherSpec){
- if(out->new == nil)
- error("change cipher without a new cipher");
- freeSec(out->sec);
- out->sec = out->new;
- out->new = nil;
- out->seq = 0;
- }
- qunlock(&out->seclock);
- poperror();
-
- /*
- * if bwrite error's, we assume the block is queued.
- * if not, we're out of sync with the receiver and will not recover.
- */
- if(waserror()){
- if(strcmp(up->errstr, "interrupted") != 0)
- tlsError(tr, "channel error");
- else if(bb != nil)
- continue;
- nexterror();
- }
- devtab[tr->c->type]->bwrite(tr->c, nb, 0);
- poperror();
- }
- qunlock(&out->io);
- poperror();
-}
-
-static long
-tlsbwrite(Chan *c, Block *b, ulong offset)
-{
- int ty;
- ulong n;
- TlsRec *tr;
-
- n = BLEN(b);
-
- tr = tlsdevs[CONV(c->qid)];
- if(tr == nil)
- panic("tlsbwrite");
-
- ty = TYPE(c->qid);
- switch(ty) {
- default:
- return devbwrite(c, b, offset);
- case Qhand:
- tlsrecwrite(tr, RHandshake, b);
- tr->handout += n;
- break;
- case Qdata:
- tlsrecwrite(tr, RApplication, b);
- tr->dataout += n;
- break;
- }
-
- return n;
-}
-
-typedef struct Hashalg Hashalg;
-struct Hashalg
-{
- char *name;
- int maclen;
- void (*initkey)(Hashalg *, int, Secret *, uchar*);
-};
-
-static void
-initmd5key(Hashalg *ha, int version, Secret *s, uchar *p)
-{
- s->maclen = ha->maclen;
- if(version == SSL3Version)
- s->mac = sslmac_md5;
- else
- s->mac = hmac_md5;
- memmove(s->mackey, p, ha->maclen);
-}
-
-static void
-initclearmac(Hashalg *ha, int version, Secret *s, uchar *p)
-{
- s->mac = nomac;
-}
-
-static void
-initsha1key(Hashalg *ha, int version, Secret *s, uchar *p)
-{
- s->maclen = ha->maclen;
- if(version == SSL3Version)
- s->mac = sslmac_sha1;
- else
- s->mac = hmac_sha1;
- memmove(s->mackey, p, ha->maclen);
-}
-
-static void
-initsha2_256key(Hashalg *ha, int version, Secret *s, uchar *p)
-{
- if(version == SSL3Version)
- error("sha256 cannot be used with SSL");
- s->maclen = ha->maclen;
- s->mac = hmac_sha2_256;
- memmove(s->mackey, p, ha->maclen);
-}
-
-static Hashalg hashtab[] =
-{
- { "clear", 0, initclearmac, },
- { "md5", MD5dlen, initmd5key, },
- { "sha1", SHA1dlen, initsha1key, },
- { "sha256", SHA2_256dlen, initsha2_256key, },
- { 0 }
-};
-
-static Hashalg*
-parsehashalg(char *p)
-{
- Hashalg *ha;
-
- for(ha = hashtab; ha->name; ha++)
- if(strcmp(p, ha->name) == 0)
- return ha;
- error("unsupported hash algorithm");
- return nil;
-}
-
-typedef struct Encalg Encalg;
-struct Encalg
-{
- char *name;
- int keylen;
- int ivlen;
- void (*initkey)(Encalg *ea, Secret *, uchar*, uchar*);
-};
-
-static void
-initRC4key(Encalg *ea, Secret *s, uchar *p, uchar *iv)
-{
- s->enckey = secalloc(sizeof(RC4state));
- s->enc = rc4enc;
- s->dec = rc4enc;
- setupRC4state(s->enckey, p, ea->keylen);
-}
-
-static void
-initDES3key(Encalg *ea, Secret *s, uchar *p, uchar *iv)
-{
- s->enckey = secalloc(sizeof(DES3state));
- s->enc = des3enc;
- s->dec = des3dec;
- s->block = 8;
- setupDES3state(s->enckey, (uchar(*)[8])p, iv);
-}
-
-static void
-initAESkey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
-{
- s->enckey = secalloc(sizeof(AESstate));
- s->enc = aesenc;
- s->dec = aesdec;
- s->block = 16;
- setupAESstate(s->enckey, p, ea->keylen, iv);
-}
-
-static void
-initccpolykey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
-{
- s->enckey = secalloc(sizeof(Chachastate));
- s->aead_enc = ccpoly_aead_enc;
- s->aead_dec = ccpoly_aead_dec;
- s->maclen = Poly1305dlen;
- if(ea->ivlen == 0) {
- /* older draft version, iv is 64-bit sequence number */
- setupChachastate(s->enckey, p, ea->keylen, nil, 64/8, 20);
- } else {
- /* IETF standard, 96-bit iv xored with sequence number */
- memmove(s->mackey, iv, ea->ivlen);
- setupChachastate(s->enckey, p, ea->keylen, iv, ea->ivlen, 20);
- }
-}
-
-static void
-initaesgcmkey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
-{
- s->enckey = secalloc(sizeof(AESGCMstate));
- s->aead_enc = aesgcm_aead_enc;
- s->aead_dec = aesgcm_aead_dec;
- s->maclen = 16;
- s->recivlen = 8;
- memmove(s->mackey, iv, ea->ivlen);
- prng(s->mackey + ea->ivlen, s->recivlen);
- setupAESGCMstate(s->enckey, p, ea->keylen, nil, 0);
-}
-
-static void
-initclearenc(Encalg *ea, Secret *s, uchar *key, uchar *iv)
-{
- s->enc = noenc;
- s->dec = noenc;
-}
-
-static Encalg encrypttab[] =
-{
- { "clear", 0, 0, initclearenc },
- { "rc4_128", 128/8, 0, initRC4key },
- { "3des_ede_cbc", 3 * 8, 8, initDES3key },
- { "aes_128_cbc", 128/8, 16, initAESkey },
- { "aes_256_cbc", 256/8, 16, initAESkey },
- { "ccpoly64_aead", 256/8, 0, initccpolykey },
- { "ccpoly96_aead", 256/8, 96/8, initccpolykey },
- { "aes_128_gcm_aead", 128/8, 4, initaesgcmkey },
- { "aes_256_gcm_aead", 256/8, 4, initaesgcmkey },
- { 0 }
-};
-
-static Encalg*
-parseencalg(char *p)
-{
- Encalg *ea;
-
- for(ea = encrypttab; ea->name; ea++)
- if(strcmp(p, ea->name) == 0)
- return ea;
- error("unsupported encryption algorithm");
- return nil;
-}
-
-static long
-tlswrite(Chan *c, void *a, long n, vlong off)
-{
- Encalg *ea;
- Hashalg *ha;
- TlsRec *volatile tr;
- Secret *volatile tos, *volatile toc;
- Block *volatile b;
- Cmdbuf *volatile cb;
- int m, ty;
- char *p, *e;
- uchar *volatile x;
- ulong offset = off;
-
- tr = tlsdevs[CONV(c->qid)];
- if(tr == nil)
- panic("tlswrite");
-
- ty = TYPE(c->qid);
- switch(ty){
- case Qdata:
- case Qhand:
- p = a;
- e = p + n;
- do{
- m = e - p;
- if(m > c->iounit)
- m = c->iounit;
-
- b = allocb(m);
- if(waserror()){
- freeb(b);
- nexterror();
- }
- memmove(b->wp, p, m);
- poperror();
- b->wp += m;
-
- tlsbwrite(c, b, offset);
- offset += m;
-
- p += m;
- }while(p < e);
- return n;
- case Qctl:
- break;
- default:
- error(Ebadusefd);
- return -1;
- }
-
- cb = parsecmd(a, n);
- if(waserror()){
- free(cb);
- nexterror();
- }
- if(cb->nf < 1)
- error("short control request");
-
- /* mutex with operations using what we're about to change */
- if(waserror()){
- qunlock(&tr->in.seclock);
- qunlock(&tr->out.seclock);
- nexterror();
- }
- qlock(&tr->in.seclock);
- qlock(&tr->out.seclock);
-
- if(strcmp(cb->f[0], "fd") == 0){
- if(cb->nf != 3)
- error("usage: fd open-fd version");
- if(tr->c != nil)
- error(Einuse);
- m = strtol(cb->f[2], nil, 0);
- if(m < MinProtoVersion || m > MaxProtoVersion)
- error("unsupported version");
- tr->c = buftochan(cb->f[1]);
- tr->version = m;
- tlsSetState(tr, SHandshake, SClosed);
- }else if(strcmp(cb->f[0], "version") == 0){
- if(cb->nf != 2)
- error("usage: version vers");
- if(tr->c == nil)
- error("must set fd before version");
- if(tr->verset)
- error("version already set");
- m = strtol(cb->f[1], nil, 0);
- if(m < MinProtoVersion || m > MaxProtoVersion)
- error("unsupported version");
- if(m == SSL3Version)
- tr->packAAD = sslPackAAD;
- else
- tr->packAAD = tlsPackAAD;
- tr->verset = 1;
- tr->version = m;
- }else if(strcmp(cb->f[0], "secret") == 0){
- if(cb->nf != 5)
- error("usage: secret hashalg encalg isclient secretdata");
- if(tr->c == nil || !tr->verset)
- error("must set fd and version before secrets");
-
- if(tr->in.new != nil){
- freeSec(tr->in.new);
- tr->in.new = nil;
- }
- if(tr->out.new != nil){
- freeSec(tr->out.new);
- tr->out.new = nil;
- }
-
- ha = parsehashalg(cb->f[1]);
- ea = parseencalg(cb->f[2]);
-
- p = cb->f[4];
- m = (strlen(p)*3)/2 + 1;
- x = secalloc(m);
- tos = secalloc(sizeof(Secret));
- toc = secalloc(sizeof(Secret));
- if(waserror()){
- secfree(x);
- freeSec(tos);
- freeSec(toc);
- nexterror();
- }
-
- m = dec64(x, m, p, strlen(p));
- memset(p, 0, strlen(p));
- if(m < 2 * ha->maclen + 2 * ea->keylen + 2 * ea->ivlen)
- error("not enough secret data provided");
-
- if(!ha->initkey || !ea->initkey)
- error("misimplemented secret algorithm");
-
- (*ha->initkey)(ha, tr->version, tos, &x[0]);
- (*ha->initkey)(ha, tr->version, toc, &x[ha->maclen]);
- (*ea->initkey)(ea, tos, &x[2 * ha->maclen], &x[2 * ha->maclen + 2 * ea->keylen]);
- (*ea->initkey)(ea, toc, &x[2 * ha->maclen + ea->keylen], &x[2 * ha->maclen + 2 * ea->keylen + ea->ivlen]);
-
- if(!tos->aead_enc || !tos->aead_dec || !toc->aead_enc || !toc->aead_dec)
- if(!tos->mac || !tos->enc || !tos->dec || !toc->mac || !toc->enc || !toc->dec)
- error("missing algorithm implementations");
-
- if(strtol(cb->f[3], nil, 0) == 0){
- tr->in.new = tos;
- tr->out.new = toc;
- }else{
- tr->in.new = toc;
- tr->out.new = tos;
- }
- if(tr->version == SSL3Version){
- toc->unpad = sslunpad;
- tos->unpad = sslunpad;
- }else{
- toc->unpad = tlsunpad;
- tos->unpad = tlsunpad;
- }
- toc->encalg = ea->name;
- toc->hashalg = ha->name;
- tos->encalg = ea->name;
- tos->hashalg = ha->name;
-
- secfree(x);
- poperror();
- }else if(strcmp(cb->f[0], "changecipher") == 0){
- if(cb->nf != 1)
- error("usage: changecipher");
- if(tr->out.new == nil)
- error("cannot change cipher spec without setting secret");
-
- qunlock(&tr->in.seclock);
- qunlock(&tr->out.seclock);
- poperror();
- free(cb);
- poperror();
-
- /*
- * the real work is done as the message is written
- * so the stream is encrypted in sync.
- */
- b = allocb(1);
- *b->wp++ = 1;
- tlsrecwrite(tr, RChangeCipherSpec, b);
- return n;
- }else if(strcmp(cb->f[0], "opened") == 0){
- if(cb->nf != 1)
- error("usage: opened");
- if(tr->in.sec == nil || tr->out.sec == nil)
- error("cipher must be configured before enabling data messages");
- lock(&tr->statelk);
- if(tr->state != SHandshake && tr->state != SOpen){
- unlock(&tr->statelk);
- error("cannot enable data messages");
- }
- tr->state = SOpen;
- unlock(&tr->statelk);
- tr->opened = 1;
- }else if(strcmp(cb->f[0], "alert") == 0){
- if(cb->nf != 2)
- error("usage: alert n");
- m = strtol(cb->f[1], nil, 0);
- Hangup:
- if(tr->c == nil)
- error("must set fd before sending alerts");
- qunlock(&tr->in.seclock);
- qunlock(&tr->out.seclock);
- poperror();
- free(cb);
- poperror();
-
- sendAlert(tr, m);
-
- if(m == ECloseNotify)
- tlsclosed(tr, SLClose);
-
- return n;
- } else if(strcmp(cb->f[0], "hangup") == 0){
- m = ECloseNotify;
- goto Hangup;
- } else if(strcmp(cb->f[0], "debug") == 0){
- if(cb->nf == 2){
- if(strcmp(cb->f[1], "on") == 0)
- tr->debug = 1;
- else
- tr->debug = 0;
- } else
- tr->debug = 1;
- } else
- error(Ebadarg);
-
- qunlock(&tr->in.seclock);
- qunlock(&tr->out.seclock);
- poperror();
- free(cb);
- poperror();
-
- return n;
-}
-
-static void
-tlsinit(void)
-{
- struct Encalg *e;
- struct Hashalg *h;
- int n;
- char *cp;
-
- fmtinstall('H', encodefmt);
-
- tlsdevs = smalloc(sizeof(TlsRec*) * maxtlsdevs);
- trnames = smalloc((sizeof *trnames) * maxtlsdevs);
-
- n = 1;
- for(e = encrypttab; e->name != nil; e++)
- n += strlen(e->name) + 1;
- cp = encalgs = smalloc(n);
- for(e = encrypttab;;){
- strcpy(cp, e->name);
- cp += strlen(e->name);
- e++;
- if(e->name == nil)
- break;
- *cp++ = ' ';
- }
- *cp = 0;
-
- n = 1;
- for(h = hashtab; h->name != nil; h++)
- n += strlen(h->name) + 1;
- cp = hashalgs = smalloc(n);
- for(h = hashtab;;){
- strcpy(cp, h->name);
- cp += strlen(h->name);
- h++;
- if(h->name == nil)
- break;
- *cp++ = ' ';
- }
- *cp = 0;
-}
-
-Dev tlsdevtab = {
- 'a',
- "tls",
-
- devreset,
- tlsinit,
- devshutdown,
- tlsattach,
- tlswalk,
- tlsstat,
- tlsopen,
- devcreate,
- tlsclose,
- tlsread,
- tlsbread,
- tlswrite,
- tlsbwrite,
- devremove,
- tlswstat,
-};
-
-/* get channel associated with an fd */
-static Chan*
-buftochan(char *p)
-{
- Chan *c;
- int fd;
-
- if(p == 0)
- error(Ebadarg);
- fd = strtoul(p, 0, 0);
- if(fd < 0)
- error(Ebadarg);
- c = fdtochan(fd, ORDWR, 1, 1); /* error check and inc ref */
- return c;
-}
-
-static void
-sendAlert(TlsRec *tr, int err)
-{
- Block *b;
- int i, fatal;
- char *msg;
-
-if(tr->debug)pprint("sendAlert %d\n", err);
- fatal = 1;
- msg = "tls unknown alert";
- for(i=0; i < nelem(tlserrs); i++) {
- if(tlserrs[i].err == err) {
- msg = tlserrs[i].msg;
- if(tr->version == SSL3Version)
- err = tlserrs[i].sslerr;
- else
- err = tlserrs[i].tlserr;
- fatal = tlserrs[i].fatal;
- break;
- }
- }
-
- if(!waserror()){
- b = allocb(2);
- *b->wp++ = fatal + 1;
- *b->wp++ = err;
- if(fatal)
- tlsSetState(tr, SAlert, SOpen|SHandshake|SRClose);
- tlsrecwrite(tr, RAlert, b);
- poperror();
- }
- if(fatal)
- tlsError(tr, msg);
-}
-
-static void
-tlsError(TlsRec *tr, char *msg)
-{
- int s;
-
-if(tr->debug)pprint("tlsError %s\n", msg);
- lock(&tr->statelk);
- s = tr->state;
- tr->state = SError;
- if(s != SError){
- strncpy(tr->err, msg, ERRMAX - 1);
- tr->err[ERRMAX - 1] = '\0';
- }
- unlock(&tr->statelk);
- if(s != SError)
- alertHand(tr, msg);
-}
-
-static void
-tlsSetState(TlsRec *tr, int new, int old)
-{
- lock(&tr->statelk);
- if(tr->state & old)
- tr->state = new;
- unlock(&tr->statelk);
-}
-
-/* hand up a digest connection */
-static void
-tlshangup(TlsRec *tr)
-{
- Block *b;
-
- qlock(&tr->in.io);
- for(b = tr->processed; b; b = tr->processed){
- tr->processed = b->next;
- freeb(b);
- }
- if(tr->unprocessed != nil){
- freeb(tr->unprocessed);
- tr->unprocessed = nil;
- }
- qunlock(&tr->in.io);
-
- tlsSetState(tr, SClosed, ~0);
-}
-
-static TlsRec*
-newtls(Chan *ch)
-{
- TlsRec **pp, **ep, **np;
- char **nmp;
- int t, newmax;
-
- if(waserror()) {
- unlock(&tdlock);
- nexterror();
- }
- lock(&tdlock);
- ep = &tlsdevs[maxtlsdevs];
- for(pp = tlsdevs; pp < ep; pp++)
- if(*pp == nil)
- break;
- if(pp >= ep) {
- if(maxtlsdevs >= MaxTlsDevs) {
- unlock(&tdlock);
- poperror();
- return nil;
- }
- newmax = 2 * maxtlsdevs;
- if(newmax > MaxTlsDevs)
- newmax = MaxTlsDevs;
- np = smalloc(sizeof(TlsRec*) * newmax);
- memmove(np, tlsdevs, sizeof(TlsRec*) * maxtlsdevs);
- tlsdevs = np;
- pp = &tlsdevs[maxtlsdevs];
- memset(pp, 0, sizeof(TlsRec*)*(newmax - maxtlsdevs));
-
- nmp = smalloc(sizeof *nmp * newmax);
- memmove(nmp, trnames, sizeof *nmp * maxtlsdevs);
- trnames = nmp;
-
- maxtlsdevs = newmax;
- }
- *pp = mktlsrec();
- if(pp - tlsdevs >= tdhiwat)
- tdhiwat++;
- t = TYPE(ch->qid);
- if(t == Qclonus)
- t = Qctl;
- ch->qid.path = QID(pp - tlsdevs, t);
- ch->qid.vers = 0;
- unlock(&tdlock);
- poperror();
- return *pp;
-}
-
-static TlsRec *
-mktlsrec(void)
-{
- TlsRec *tr;
-
- tr = mallocz(sizeof(*tr), 1);
- if(tr == nil)
- error(Enomem);
- tr->state = SClosed;
- tr->ref = 1;
- kstrdup(&tr->user, up->user);
- tr->perm = 0660;
- return tr;
-}
-
-static char*
-tlsstate(int s)
-{
- switch(s){
- case SHandshake:
- return "Handshaking";
- case SOpen:
- return "Established";
- case SRClose:
- return "RemoteClosed";
- case SLClose:
- return "LocalClosed";
- case SAlert:
- return "Alerting";
- case SError:
- return "Errored";
- case SClosed:
- return "Closed";
- }
- return "Unknown";
-}
-
-static void
-freeSec(Secret *s)
-{
- if(s == nil)
- return;
- secfree(s->enckey);
- secfree(s);
-}
-
-static int
-noenc(Secret *sec, uchar *buf, int n)
-{
- return n;
-}
-
-static int
-rc4enc(Secret *sec, uchar *buf, int n)
-{
- rc4(sec->enckey, buf, n);
- return n;
-}
-
-static int
-tlsunpad(uchar *buf, int n, int block)
-{
- int pad, nn;
-
- pad = buf[n - 1];
- nn = n - 1 - pad;
- if(nn <= 0 || n % block)
- return -1;
- while(--n > nn)
- if(pad != buf[n - 1])
- return -1;
- return nn;
-}
-
-static int
-sslunpad(uchar *buf, int n, int block)
-{
- int pad, nn;
-
- pad = buf[n - 1];
- nn = n - 1 - pad;
- if(nn <= 0 || n % block)
- return -1;
- return nn;
-}
-
-static int
-blockpad(uchar *buf, int n, int block)
-{
- int pad, nn;
-
- nn = n + block;
- nn -= nn % block;
- pad = nn - (n + 1);
- while(n < nn)
- buf[n++] = pad;
- return nn;
-}
-
-static int
-des3enc(Secret *sec, uchar *buf, int n)
-{
- n = blockpad(buf, n, 8);
- des3CBCencrypt(buf, n, sec->enckey);
- return n;
-}
-
-static int
-des3dec(Secret *sec, uchar *buf, int n)
-{
- des3CBCdecrypt(buf, n, sec->enckey);
- return (*sec->unpad)(buf, n, 8);
-}
-
-static int
-aesenc(Secret *sec, uchar *buf, int n)
-{
- n = blockpad(buf, n, 16);
- aesCBCencrypt(buf, n, sec->enckey);
- return n;
-}
-
-static int
-aesdec(Secret *sec, uchar *buf, int n)
-{
- aesCBCdecrypt(buf, n, sec->enckey);
- return (*sec->unpad)(buf, n, 16);
-}
-
-static void
-ccpoly_aead_setiv(Secret *sec, uchar seq[8])
-{
- uchar iv[ChachaIVlen];
- Chachastate *cs;
- int i;
-
- cs = (Chachastate*)sec->enckey;
- if(cs->ivwords == 2){
- chacha_setiv(cs, seq);
- return;
- }
-
- memmove(iv, sec->mackey, ChachaIVlen);
- for(i=0; i<8; i++)
- iv[i+(ChachaIVlen-8)] ^= seq[i];
-
- chacha_setiv(cs, iv);
-
- memset(iv, 0, sizeof(iv));
-}
-
-static int
-ccpoly_aead_enc(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data, int len)
-{
- USED(reciv);
- ccpoly_aead_setiv(sec, aad);
- ccpoly_encrypt(data, len, aad, aadlen, data+len, sec->enckey);
- return len + sec->maclen;
-}
-
-static int
-ccpoly_aead_dec(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data, int len)
-{
- USED(reciv);
- len -= sec->maclen;
- if(len < 0)
- return -1;
- ccpoly_aead_setiv(sec, aad);
- if(ccpoly_decrypt(data, len, aad, aadlen, data+len, sec->enckey) != 0)
- return -1;
- return len;
-}
-
-static int
-aesgcm_aead_enc(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data, int len)
-{
- uchar iv[12];
- int i;
-
- memmove(iv, sec->mackey, 4+8);
- for(i=0; i<8; i++) iv[4+i] ^= aad[i];
- memmove(reciv, iv+4, 8);
- aesgcm_setiv(sec->enckey, iv, 12);
- memset(iv, 0, sizeof(iv));
- aesgcm_encrypt(data, len, aad, aadlen, data+len, sec->enckey);
- return len + sec->maclen;
-}
-
-static int
-aesgcm_aead_dec(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data, int len)
-{
- uchar iv[12];
-
- len -= sec->maclen;
- if(len < 0)
- return -1;
- memmove(iv, sec->mackey, 4);
- memmove(iv+4, reciv, 8);
- aesgcm_setiv(sec->enckey, iv, 12);
- memset(iv, 0, sizeof(iv));
- if(aesgcm_decrypt(data, len, aad, aadlen, data+len, sec->enckey) != 0)
- return -1;
- return len;
-}
-
-
-static DigestState*
-nomac(uchar *p, ulong len, uchar *key, ulong keylen, uchar *digest, DigestState *s)
-{
- return nil;
-}
-
-/*
- * sslmac: mac calculations for ssl 3.0 only; tls 1.0 uses the standard hmac.
- */
-static DigestState*
-sslmac_x(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s,
- DigestState*(*x)(uchar*, ulong, uchar*, DigestState*), int xlen, int padlen)
-{
- int i;
- uchar pad[48], innerdigest[20];
-
- if(xlen > sizeof(innerdigest)
- || padlen > sizeof(pad))
- return nil;
-
- if(klen>64)
- return nil;
-
- /* first time through */
- if(s == nil){
- for(i=0; i<padlen; i++)
- pad[i] = 0x36;
- s = (*x)(key, klen, nil, nil);
- s = (*x)(pad, padlen, nil, s);
- if(s == nil)
- return nil;
- }
-
- s = (*x)(p, len, nil, s);
- if(digest == nil)
- return s;
-
- /* last time through */
- for(i=0; i<padlen; i++)
- pad[i] = 0x5c;
- (*x)(nil, 0, innerdigest, s);
- s = (*x)(key, klen, nil, nil);
- s = (*x)(pad, padlen, nil, s);
- (*x)(innerdigest, xlen, digest, s);
- return nil;
-}
-
-static DigestState*
-sslmac_sha1(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s)
-{
- return sslmac_x(p, len, key, klen, digest, s, sha1, SHA1dlen, 40);
-}
-
-static DigestState*
-sslmac_md5(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s)
-{
- return sslmac_x(p, len, key, klen, digest, s, md5, MD5dlen, 48);
-}
-
-static int
-sslPackAAD(u64int seq, uchar *hdr, uchar *aad)
-{
- put64(aad, seq);
- aad[8] = hdr[0];
- aad[9] = hdr[3];
- aad[10] = hdr[4];
- return 11;
-}
-
-static int
-tlsPackAAD(u64int seq, uchar *hdr, uchar *aad)
-{
- put64(aad, seq);
- aad[8] = hdr[0];
- aad[9] = hdr[1];
- aad[10] = hdr[2];
- aad[11] = hdr[3];
- aad[12] = hdr[4];
- return 13;
-}
-
-static void
-packMac(Secret *sec, uchar *aad, int aadlen, uchar *body, int bodylen, uchar *mac)
-{
- DigestState *s;
-
- s = (*sec->mac)(aad, aadlen, sec->mackey, sec->maclen, nil, nil);
- (*sec->mac)(body, bodylen, sec->mackey, sec->maclen, mac, s);
-}
-
-static void
-put32(uchar *p, u32int x)
-{
- p[0] = x>>24;
- p[1] = x>>16;
- p[2] = x>>8;
- p[3] = x;
-}
-
-static void
-put64(uchar *p, u64int x)
-{
- put32(p, x >> 32);
- put32(p+4, x);
-}
-
-static void
-put24(uchar *p, int x)
-{
- p[0] = x>>16;
- p[1] = x>>8;
- p[2] = x;
-}
-
-static void
-put16(uchar *p, int x)
-{
- p[0] = x>>8;
- p[1] = x;
-}
-
-static int
-get16(uchar *p)
-{
- return (p[0]<<8)|p[1];
-}
-
-static char *charmap = "0123456789abcdef";
-
-static void
-pdump(int len, void *a, char *tag)
-{
- uchar *p;
- int i;
- char buf[65+32];
- char *q;
-
- p = a;
- strcpy(buf, tag);
- while(len > 0){
- q = buf + strlen(tag);
- for(i = 0; len > 0 && i < 32; i++){
- if(*p >= ' ' && *p < 0x7f){
- *q++ = ' ';
- *q++ = *p;
- } else {
- *q++ = charmap[*p>>4];
- *q++ = charmap[*p & 0xf];
- }
- len--;
- p++;
- }
- *q = 0;
-
- if(len > 0)
- pprint("%s...\n", buf);
- else
- pprint("%s\n", buf);
- }
-}
--- a/kern/term.c
+++ /dev/null
@@ -1,242 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-
-#include <draw.h>
-#include <memdraw.h>
-#include "screen.h"
-
-extern Memimage *gscreen;
-
-static Memsubfont *memdefont;
-static Lock screenlock;
-static Memimage *conscol;
-static Memimage *back;
-static Rectangle flushr;
-static Rectangle window;
-static Point curpos;
-static int h;
-
-static void termscreenputs(char*, int);
-
-static void
-screenflush(void)
-{
- flushmemscreen(flushr);
- flushr = Rect(10000, 10000, -10000, -10000);
-}
-
-static void
-addflush(Rectangle r)
-{
- if(flushr.min.x >= flushr.max.x)
- flushr = r;
- else
- combinerect(&flushr, r);
-}
-
-static void
-screenwin(void)
-{
- Point p;
- char *greet;
- Memimage *grey;
-
- back = memwhite;
- conscol = memblack;
- memfillcolor(gscreen, 0x444488FF);
-
- h = memdefont->height;
-
- window = insetrect(gscreen->clipr, 20);
- memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP, S);
- window = insetrect(window, 4);
- memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);
-
- /* a lot of work to get a grey color */
- grey = allocmemimage(Rect(0,0,1,1), CMAP8);
- grey->flags |= Frepl;
- grey->clipr = gscreen->r;
- memfillcolor(grey, 0xAAAAAAFF);
- memimagedraw(gscreen, Rect(window.min.x, window.min.y,
- window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP, S);
- freememimage(grey);
- window = insetrect(window, 5);
-
- greet = " Plan 9 Console ";
- p = addpt(window.min, Pt(10, 0));
- memimagestring(gscreen, p, conscol, ZP, memdefont, greet);
- window.min.y += h+6;
- curpos = window.min;
- window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
- flushmemscreen(gscreen->r);
-
- termscreenputs(kmesg.buf, kmesg.n);
-}
-
-static struct {
- Rectangle r;
- Rendez z;
- int f;
-} resize;
-
-static int
-isresized(void *arg)
-{
- return resize.f != 0;
-}
-
-static void
-resizeproc(void *arg)
-{
- USED(arg);
- for(;;){
- sleep(&resize.z, isresized, nil);
- qlock(&drawlock);
- resize.f = 0;
- if(gscreen == nil
- || badrect(resize.r)
- || eqrect(resize.r, gscreen->clipr)){
- qunlock(&drawlock);
- continue;
- }
- screensize(resize.r, gscreen->chan);
- if(gscreen == nil
- || rectclip(&resize.r, gscreen->r) == 0
- || eqrect(resize.r, gscreen->clipr)){
- qunlock(&drawlock);
- continue;
- }
- gscreen->clipr = resize.r;
-
- screenwin();
- deletescreenimage();
- resetscreenimage();
- qunlock(&drawlock);
- osmsleep(1000);
- }
-}
-
-void
-screenresize(Rectangle r)
-{
- qlock(&drawlock);
- resize.r = r;
- resize.f = 1;
- wakeup(&resize.z);
- qunlock(&drawlock);
-}
-
-void
-terminit(void)
-{
- memdefont = getmemdefont();
- screenwin();
- screenputs = termscreenputs;
- kproc("resize", resizeproc, nil);
-}
-
-static void
-scroll(void)
-{
- int o;
- Point p;
- Rectangle r;
-
- o = 8*h;
- r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
- p = Pt(window.min.x, window.min.y+o);
- memimagedraw(gscreen, r, gscreen, p, nil, p, S);
- r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
- memimagedraw(gscreen, r, back, ZP, nil, ZP, S);
- curpos.y -= o;
-}
-
-static void
-screenputc(char *buf)
-{
- Point p;
- int w, pos;
- Rectangle r;
- static int *xp;
- static int xbuf[256];
-
- if(xp < xbuf || xp >= &xbuf[nelem(xbuf)])
- xp = xbuf;
-
- switch(buf[0]) {
- case '\n':
- if(curpos.y+h >= window.max.y){
- scroll();
- flushr = window;
- }
- curpos.y += h;
- screenputc("\r");
- break;
- case '\r':
- xp = xbuf;
- curpos.x = window.min.x;
- break;
- case '\t':
- p = memsubfontwidth(memdefont, " ");
- w = p.x;
- *xp++ = curpos.x;
- pos = (curpos.x-window.min.x)/w;
- pos = 8-(pos%8);
- r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
- memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
- addflush(r);
- curpos.x += pos*w;
- break;
- case '\b':
- if(xp <= xbuf)
- break;
- xp--;
- r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
- memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
- addflush(r);
- curpos.x = *xp;
- break;
- default:
- p = memsubfontwidth(memdefont, buf);
- w = p.x;
-
- if(curpos.x >= window.max.x-w)
- screenputc("\n");
-
- *xp++ = curpos.x;
- r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h);
- memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
- memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
- addflush(r);
- curpos.x += w;
- }
-}
-
-static void
-termscreenputs(char *s, int n)
-{
- static char rb[UTFmax+1];
- static int nrb;
- int locked;
- char *e;
-
- lock(&screenlock);
- locked = canqlock(&drawlock);
- e = s + n;
- while(s < e){
- rb[nrb++] = *s++;
- if(nrb >= UTFmax || fullrune(rb, nrb)){
- rb[nrb] = 0;
- screenputc(rb);
- nrb = 0;
- }
- }
- if(locked){
- screenflush();
- qunlock(&drawlock);
- }
- unlock(&screenlock);
-}
--- a/libauth/Makefile
+++ /dev/null
@@ -1,18 +1,0 @@
-ROOT=..
-include ../Make.config
-
-LIB=libauth.a
-OFILES=\
- attr.$O\
- auth_attr.$O\
- auth_proxy.$O\
- auth_rpc.$O\
-
-default: $(LIB)
-$(LIB): $(OFILES)
- $(AR) r $(LIB) $(OFILES)
- $(RANLIB) $(LIB)
-
-%.$O: %.c
- $(CC) $(CFLAGS) $*.c
-
--- a/libauth/attr.c
+++ /dev/null
@@ -1,164 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <auth.h>
-
-int
-_attrfmt(Fmt *fmt)
-{
- Attr *a;
- int first = 1;
-
- for(a=va_arg(fmt->args, Attr*); a != nil; a=a->next){
- if(a->name == nil)
- continue;
- switch(a->type){
- default:
- continue;
- case AttrQuery:
- fmtprint(fmt, first+" %q?", a->name);
- break;
- case AttrNameval:
- case AttrDefault:
- fmtprint(fmt, first+" %q=%q", a->name, a->val);
- break;
- }
- first = 0;
- }
- return 0;
-}
-
-Attr*
-_copyattr(Attr *a)
-{
- Attr **la, *na;
-
- na = nil;
- la = &na;
- for(; a; a=a->next){
- *la = _mkattr(a->type, a->name, a->val, nil);
- setmalloctag(*la, getcallerpc(&a));
- la = &(*la)->next;
- }
- *la = nil;
- return na;
-}
-
-Attr*
-_delattr(Attr *a, char *name)
-{
- Attr *fa;
- Attr **la;
-
- for(la=&a; *la; ){
- if(strcmp((*la)->name, name) == 0){
- fa = *la;
- *la = (*la)->next;
- fa->next = nil;
- _freeattr(fa);
- }else
- la=&(*la)->next;
- }
- return a;
-}
-
-Attr*
-_findattr(Attr *a, char *n)
-{
- for(; a; a=a->next)
- if(strcmp(a->name, n) == 0 && a->type != AttrQuery)
- return a;
- return nil;
-}
-
-void
-_freeattr(Attr *a)
-{
- Attr *anext;
-
- for(; a; a=anext){
- anext = a->next;
- free(a->name);
- free(a->val);
- a->name = (void*)~0;
- a->val = (void*)~0;
- a->next = (void*)~0;
- free(a);
- }
-}
-
-Attr*
-_mkattr(int type, char *name, char *val, Attr *next)
-{
- Attr *a;
-
- a = malloc(sizeof(*a));
- if(a==nil)
- sysfatal("_mkattr malloc: %r");
- a->type = type;
- a->name = strdup(name);
- a->val = strdup(val);
- if(a->name==nil || a->val==nil)
- sysfatal("_mkattr malloc: %r");
- a->next = next;
- setmalloctag(a, getcallerpc(&type));
- return a;
-}
-
-static Attr*
-cleanattr(Attr *a)
-{
- Attr *fa;
- Attr **la;
-
- for(la=&a; *la; ){
- if((*la)->type==AttrQuery && _findattr(a, (*la)->name)){
- fa = *la;
- *la = (*la)->next;
- fa->next = nil;
- _freeattr(fa);
- }else
- la=&(*la)->next;
- }
- return a;
-}
-
-Attr*
-_parseattr(char *s)
-{
- char *p, *t, *tok[256];
- int i, ntok;
- Attr *a;
-
- s = strdup(s);
- if(s == nil)
- sysfatal("_parseattr strdup: %r");
-
- ntok = tokenize(s, tok, nelem(tok));
- a = nil;
- for(i=ntok-1; i>=0; i--){
- t = tok[i];
- if((p = strchr(t, '=')) != nil){
- *p++ = '\0';
- a = _mkattr(AttrNameval, t, p, a);
- }else if((p = strchr(t, '\0')-1) >= t && *p == '?'){
- *p = '\0';
- a = _mkattr(AttrQuery, t, "", a);
- }else{
- /* really a syntax error, but better to provide some indication */
- a = _mkattr(AttrNameval, t, "", a);
- }
- setmalloctag(a, getcallerpc(&s));
- }
- free(s);
- return cleanattr(a);
-}
-
-char*
-_strfindattr(Attr *a, char *n)
-{
- a = _findattr(a, n);
- if(a == nil)
- return nil;
- return a->val;
-}
-
--- a/libauth/auth_attr.c
+++ /dev/null
@@ -1,12 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <auth.h>
-#include "authlocal.h"
-
-Attr*
-auth_attr(AuthRpc *rpc)
-{
- if(auth_rpc(rpc, "attr", nil, 0) != ARok)
- return nil;
- return _parseattr(rpc->arg);
-}
--- a/libauth/auth_proxy.c
+++ /dev/null
@@ -1,218 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-#include <auth.h>
-#include "authlocal.h"
-
-enum {
- ARgiveup = 100,
-};
-
-static uchar*
-gstring(uchar *p, uchar *ep, char **s)
-{
- uint n;
-
- if(p == nil)
- return nil;
- if(p+BIT16SZ > ep)
- return nil;
- n = GBIT16(p);
- p += BIT16SZ;
- if(p+n > ep)
- return nil;
- *s = malloc(n+1);
- memmove((*s), p, n);
- (*s)[n] = '\0';
- p += n;
- return p;
-}
-
-static uchar*
-gcarray(uchar *p, uchar *ep, uchar **s, int *np)
-{
- uint n;
-
- if(p == nil)
- return nil;
- if(p+BIT16SZ > ep)
- return nil;
- n = GBIT16(p);
- p += BIT16SZ;
- if(p+n > ep)
- return nil;
- *s = malloc(n);
- if(*s == nil)
- return nil;
- memmove((*s), p, n);
- *np = n;
- p += n;
- return p;
-}
-
-void
-auth_freeAI(AuthInfo *ai)
-{
- if(ai == nil)
- return;
- free(ai->cuid);
- free(ai->suid);
- free(ai->cap);
- free(ai->secret);
- free(ai);
-}
-
-static uchar*
-convM2AI(uchar *p, int n, AuthInfo **aip)
-{
- uchar *e = p+n;
- AuthInfo *ai;
-
- ai = mallocz(sizeof(*ai), 1);
- if(ai == nil)
- return nil;
-
- p = gstring(p, e, &ai->cuid);
- p = gstring(p, e, &ai->suid);
- p = gstring(p, e, &ai->cap);
- p = gcarray(p, e, &ai->secret, &ai->nsecret);
- if(p == nil)
- auth_freeAI(ai);
- else
- *aip = ai;
- return p;
-}
-
-AuthInfo*
-auth_getinfo(AuthRpc *rpc)
-{
- AuthInfo *a;
-
- if(auth_rpc(rpc, "authinfo", nil, 0) != ARok)
- return nil;
- if(convM2AI((uchar*)rpc->arg, rpc->narg, &a) == nil){
- werrstr("bad auth info from factotum");
- return nil;
- }
- return a;
-}
-
-static int
-dorpc(AuthRpc *rpc, char *verb, char *val, int len, AuthGetkey *getkey)
-{
- int ret;
-
- for(;;){
- if((ret = auth_rpc(rpc, verb, val, len)) != ARneedkey && ret != ARbadkey)
- return ret;
- if(getkey == nil)
- return ARgiveup; /* don't know how */
- if((*getkey)(rpc->arg) < 0)
- return ARgiveup; /* user punted */
- }
-}
-
-/*
- * this just proxies what the factotum tells it to.
- */
-AuthInfo*
-fauth_proxy(int fd, AuthRpc *rpc, AuthGetkey *getkey, char *params)
-{
- char *buf;
- int m, n, ret;
- AuthInfo *a;
- char oerr[ERRMAX];
-
- if(rpc == nil){
- werrstr("fauth_proxy - no factotum");
- return nil;
- }
-
- strcpy(oerr, "UNKNOWN AUTH ERROR");
- errstr(oerr, sizeof oerr);
-
- if(dorpc(rpc, "start", params, strlen(params), getkey) != ARok){
- werrstr("fauth_proxy start: %r");
- return nil;
- }
-
- buf = malloc(AuthRpcMax);
- if(buf == nil)
- return nil;
- for(;;){
- switch(dorpc(rpc, "read", nil, 0, getkey)){
- case ARdone:
- free(buf);
- a = auth_getinfo(rpc);
- /* no error, restore whatever was there */
- errstr(oerr, sizeof oerr);
- return a;
- case ARok:
- if(write(fd, rpc->arg, rpc->narg) != rpc->narg){
- werrstr("auth_proxy write fd: %r");
- goto Error;
- }
- break;
- case ARphase:
- n = 0;
- memset(buf, 0, AuthRpcMax);
- while((ret = dorpc(rpc, "write", buf, n, getkey)) == ARtoosmall){
- m = atoi(rpc->arg);
- if(m <= n || m > AuthRpcMax)
- break;
- m = read(fd, buf + n, m - n);
- if(m <= 0){
- if(m == 0)
- werrstr("auth_proxy short read");
- else
- werrstr("auth_proxy read fd: %r");
- goto Error;
- }
- n += m;
- }
- if(ret != ARok){
- werrstr("auth_proxy rpc write: %r");
- goto Error;
- }
- break;
- default:
- werrstr("auth_proxy rpc: %r");
- goto Error;
- }
- }
-Error:
- free(buf);
- return nil;
-}
-
-AuthInfo*
-auth_proxy(int fd, AuthGetkey *getkey, char *fmt, ...)
-{
- int afd;
- char *p;
- va_list arg;
- AuthInfo *ai;
- AuthRpc *rpc;
-
- quotefmtinstall(); /* just in case */
- va_start(arg, fmt);
- p = vsmprint(fmt, arg);
- va_end(arg);
-
- ai = nil;
- afd = open("/mnt/factotum/rpc", ORDWR);
- if(afd < 0){
- werrstr("opening /mnt/factotum/rpc: %r");
- free(p);
- return nil;
- }
-
- rpc = auth_allocrpc(afd);
- if(rpc){
- ai = fauth_proxy(fd, rpc, getkey, p);
- auth_freerpc(rpc);
- }
- close(afd);
- free(p);
- return ai;
-}
--- a/libauth/auth_rpc.c
+++ /dev/null
@@ -1,116 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <auth.h>
-#include "authlocal.h"
-
-static struct {
- char *verb;
- int val;
-} tab[] = {
- "ok", ARok,
- "done", ARdone,
- "error", ARerror,
- "needkey", ARneedkey,
- "badkey", ARbadkey,
- "phase", ARphase,
- "toosmall", ARtoosmall,
- "error", ARerror,
-};
-
-static int
-classify(char *buf, uint n, AuthRpc *rpc)
-{
- int i, len;
-
- for(i=0; i<nelem(tab); i++){
- len = strlen(tab[i].verb);
- if(n >= len && memcmp(buf, tab[i].verb, len) == 0 && (n==len || buf[len]==' ')){
- if(n==len){
- rpc->narg = 0;
- rpc->arg = "";
- }else{
- rpc->narg = n - (len+1);
- rpc->arg = (char*)buf+len+1;
- }
- return tab[i].val;
- }
- }
- werrstr("malformed rpc response: %s", buf);
- return ARrpcfailure;
-}
-
-AuthRpc*
-auth_allocrpc(int afd)
-{
- AuthRpc *rpc;
-
- rpc = mallocz(sizeof(*rpc), 1);
- if(rpc == nil)
- return nil;
- rpc->afd = afd;
- return rpc;
-}
-
-void
-auth_freerpc(AuthRpc *rpc)
-{
- free(rpc);
-}
-
-uint
-auth_rpc(AuthRpc *rpc, char *verb, void *a, int na)
-{
- int l, n, type;
- char *f[4];
-
- l = strlen(verb);
- if(na+l+1 > AuthRpcMax){
- werrstr("rpc too big");
- return ARtoobig;
- }
-
- memmove(rpc->obuf, verb, l);
- rpc->obuf[l] = ' ';
- memmove(rpc->obuf+l+1, a, na);
- if((n=write(rpc->afd, rpc->obuf, l+1+na)) != l+1+na){
- if(n >= 0)
- werrstr("auth_rpc short write");
- return ARrpcfailure;
- }
-
- if((n=read(rpc->afd, rpc->ibuf, AuthRpcMax)) < 0)
- return ARrpcfailure;
- rpc->ibuf[n] = '\0';
-
- /*
- * Set error string for good default behavior.
- */
- switch(type = classify(rpc->ibuf, n, rpc)){
- default:
- werrstr("unknown rpc type %d (bug in auth_rpc.c)", type);
- break;
- case ARok:
- break;
- case ARrpcfailure:
- break;
- case ARerror:
- if(rpc->narg == 0)
- werrstr("unspecified rpc error");
- else
- werrstr("%s", rpc->arg);
- break;
- case ARneedkey:
- werrstr("needkey %s", rpc->arg);
- break;
- case ARbadkey:
- if(getfields(rpc->arg, f, nelem(f), 0, "\n") < 2)
- werrstr("badkey %s", rpc->arg);
- else
- werrstr("badkey %s", f[1]);
- break;
- case ARphase:
- werrstr("phase error %s", rpc->arg);
- break;
- }
- return type;
-}
--- a/libauth/authlocal.h
+++ /dev/null
@@ -1,1 +1,0 @@
-extern AuthInfo* _fauth_proxy(int fd, AuthRpc *rpc, AuthGetkey *getkey, char *params);
--- a/libauthsrv/Makefile
+++ /dev/null
@@ -1,35 +1,0 @@
-ROOT=..
-include ../Make.config
-LIB=libauthsrv.a
-
-OFILES=\
- _asgetticket.$O\
- _asrdresp.$O\
- convA2M.$O\
- convM2A.$O\
- convM2PR.$O\
- convM2T.$O\
- convM2TR.$O\
- convPR2M.$O\
- convT2M.$O\
- convTR2M.$O\
- nvcsum.$O\
- passtokey.$O\
- readcons.$O\
- _asgetpakkey.$O\
- _asgetresp.$O\
- _asrequest.$O\
- authpak.$O\
- form1.$O\
-
-
-default: $(LIB)
-$(LIB): $(OFILES)
- $(AR) r $(LIB) $(OFILES)
- $(RANLIB) $(LIB)
-
-authpak.$O: msqrt.mpc edwards.mpc ed448.mpc decaf.mpc elligator2.mpc spake2ee.mpc
-
-%.$O: %.c
- $(CC) $(CFLAGS) $*.c
-
--- a/libauthsrv/_asgetpakkey.c
+++ /dev/null
@@ -1,26 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <authsrv.h>
-
-int
-_asgetpakkey(int fd, Ticketreq *tr, Authkey *a)
-{
- uchar y[PAKYLEN];
- PAKpriv p;
- int type;
-
- type = tr->type;
- tr->type = AuthPAK;
- if(_asrequest(fd, tr) != 0){
- tr->type = type;
- return -1;
- }
- tr->type = type;
- authpak_new(&p, a, y, 1);
- if(write(fd, y, PAKYLEN) != PAKYLEN
- || _asrdresp(fd, (char*)y, PAKYLEN) != PAKYLEN){
- memset(&p, 0, sizeof(p));
- return -1;
- }
- return authpak_finish(&p, a, y);
-}
--- a/libauthsrv/_asgetresp.c
+++ /dev/null
@@ -1,44 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <authsrv.h>
-
-int
-_asgetresp(int fd, Ticket *t, Authenticator *a, Authkey *k)
-{
- char buf[MAXTICKETLEN+MAXAUTHENTLEN], err[ERRMAX];
- int n, m;
-
- memset(t, 0, sizeof(Ticket));
- if(a != nil)
- memset(a, 0, sizeof(Authenticator));
-
- strcpy(err, "AS protocol botch");
- errstr(err, ERRMAX);
-
- if(_asrdresp(fd, buf, 0) < 0)
- return -1;
-
- for(n = 0; (m = convM2T(buf, n, t, k)) <= 0; n += m){
- m = -m;
- if(m <= n || m > sizeof(buf))
- return -1;
- m -= n;
- if(readn(fd, buf+n, m) != m)
- return -1;
- }
-
- if(a != nil){
- for(n = 0; (m = convM2A(buf, n, a, t)) <= 0; n += m){
- m = -m;
- if(m <= n || m > sizeof(buf))
- return -1;
- m -= n;
- if(readn(fd, buf+n, m) != m)
- return -1;
- }
- }
-
- errstr(err, ERRMAX);
-
- return 0;
-}
--- a/libauthsrv/_asgetticket.c
+++ /dev/null
@@ -1,37 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <authsrv.h>
-
-int
-_asgetticket(int fd, Ticketreq *tr, char *tbuf, int tbuflen)
-{
- char err[ERRMAX];
- int i, n, m, r;
-
- strcpy(err, "AS protocol botch");
- errstr(err, ERRMAX);
-
- if(_asrequest(fd, tr) < 0)
- return -1;
- if(_asrdresp(fd, tbuf, 0) < 0)
- return -1;
-
- r = 0;
- for(i = 0; i<2; i++){
- for(n=0; (m = convM2T(tbuf, n, nil, nil)) <= 0; n += m){
- m = -m;
- if(m <= n || m > tbuflen)
- return -1;
- m -= n;
- if(readn(fd, tbuf+n, m) != m)
- return -1;
- }
- r += n;
- tbuf += n;
- tbuflen -= n;
- }
-
- errstr(err, ERRMAX);
-
- return r;
-}
--- a/libauthsrv/_asrdresp.c
+++ /dev/null
@@ -1,56 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <authsrv.h>
-
-static char *pbmsg = "AS protocol botch";
-
-int
-_asrdresp(int fd, char *buf, int len)
-{
- int n;
- char error[64];
-
- if(read(fd, buf, 1) != 1){
- werrstr(pbmsg);
- return -1;
- }
-
- n = len;
- switch(buf[0]){
- case AuthOK:
- if(readn(fd, buf, len) != len){
- werrstr(pbmsg);
- return -1;
- }
- break;
- case AuthErr:
- if(readn(fd, error, sizeof error) != sizeof error){
- werrstr(pbmsg);
- return -1;
- }
- error[sizeof error-1] = '\0';
- werrstr("remote: %s", error);
- return -1;
- case AuthOKvar:
- if(readn(fd, error, 5) != 5){
- werrstr(pbmsg);
- return -1;
- }
- error[5] = 0;
- n = atoi(error);
- if(n <= 0 || n > len){
- werrstr(pbmsg);
- return -1;
- }
- memset(buf, 0, len);
- if(readn(fd, buf, n) != n){
- werrstr(pbmsg);
- return -1;
- }
- break;
- default:
- werrstr(pbmsg);
- return -1;
- }
- return n;
-}
--- a/libauthsrv/_asrequest.c
+++ /dev/null
@@ -1,16 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <authsrv.h>
-
-int
-_asrequest(int fd, Ticketreq *tr)
-{
- char trbuf[TICKREQLEN];
- int n;
-
- n = convTR2M(tr, trbuf, sizeof(trbuf));
- if(write(fd, trbuf, n) != n)
- return -1;
-
- return 0;
-}
--- a/libauthsrv/authdial.c
+++ /dev/null
@@ -1,50 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <authsrv.h>
-#include <bio.h>
-#include <ndb.h>
-
-int
-authdial(char *netroot, char *dom)
-{
- Ndbtuple *t, *nt;
- char *p;
- int rv;
-
- if(dom == nil)
- /* look for one relative to my machine */
- return dial(netmkaddr("$auth", nil, "ticket"), nil, nil, nil);
-
- /* look up an auth server in an authentication domain */
- p = csgetvalue(netroot, "authdom", dom, "auth", &t);
-
- /* if that didn't work, just try the IP domain */
- if(p == nil)
- p = csgetvalue(netroot, "dom", dom, "auth", &t);
-
- /*
- * if that didn't work, try p9auth.$dom. this is very helpful if
- * you can't edit /lib/ndb.
- */
- if(p == nil) {
- p = smprint("p9auth.%s", dom);
- t = ndbnew("auth", p);
- }
- free(p);
-
- /*
- * allow multiple auth= attributes for backup auth servers,
- * try each one in order.
- */
- rv = -1;
- for(nt = t; nt != nil; nt = nt->entry) {
- if(strcmp(nt->attr, "auth") == 0) {
- rv = dial(netmkaddr(nt->val, nil, "ticket"), nil, nil, nil);
- if(rv >= 0)
- break;
- }
- }
- ndbfree(t);
-
- return rv;
-}
--- a/libauthsrv/authpak.c
+++ /dev/null
@@ -1,214 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <mp.h>
-#include <libsec.h>
-#include <authsrv.h>
-
-#include "msqrt.mpc"
-#include "decaf.mpc"
-#include "edwards.mpc"
-#include "elligator2.mpc"
-#include "spake2ee.mpc"
-#include "ed448.mpc"
-
-typedef struct PAKcurve PAKcurve;
-struct PAKcurve
-{
- Lock lk;
- mpint *P;
- mpint *A;
- mpint *D;
- mpint *X;
- mpint *Y;
-};
-
-static PAKcurve*
-authpak_curve(void)
-{
- static PAKcurve a;
-
- lock(&a.lk);
- if(a.P == nil){
- a.P = mpnew(0);
- a.A = mpnew(0);
- a.D = mpnew(0);
- a.X = mpnew(0);
- a.Y = mpnew(0);
- ed448_curve(a.P, a.A, a.D, a.X, a.Y);
- a.P = mpfield(a.P);
- }
- unlock(&a.lk);
- return &a;
-}
-
-void
-authpak_hash(Authkey *k, char *u)
-{
- static char info[] = "Plan 9 AuthPAK hash";
- uchar *bp, salt[SHA2_256dlen], h[2*PAKSLEN];
- mpint *H, *PX,*PY,*PZ,*PT;
- PAKcurve *c;
-
- H = mpnew(0);
- PX = mpnew(0);
- PY = mpnew(0);
- PZ = mpnew(0);
- PT = mpnew(0);
-
- sha2_256((uchar*)u, strlen(u), salt, nil);
-
- hkdf_x( salt, SHA2_256dlen,
- (uchar*)info, sizeof(info)-1,
- k->aes, AESKEYLEN,
- h, sizeof(h),
- hmac_sha2_256, SHA2_256dlen);
-
- c = authpak_curve();
-
- betomp(h + 0*PAKSLEN, PAKSLEN, H); /* HM */
- spake2ee_h2P(c->P,c->A,c->D, H, PX,PY,PZ,PT); /* PM */
-
- bp = k->pakhash;
- mptober(PX, bp, PAKSLEN), bp += PAKSLEN;
- mptober(PY, bp, PAKSLEN), bp += PAKSLEN;
- mptober(PZ, bp, PAKSLEN), bp += PAKSLEN;
- mptober(PT, bp, PAKSLEN), bp += PAKSLEN;
-
- betomp(h + 1*PAKSLEN, PAKSLEN, H); /* HN */
- spake2ee_h2P(c->P,c->A,c->D, H, PX,PY,PZ,PT); /* PN */
-
- mptober(PX, bp, PAKSLEN), bp += PAKSLEN;
- mptober(PY, bp, PAKSLEN), bp += PAKSLEN;
- mptober(PZ, bp, PAKSLEN), bp += PAKSLEN;
- mptober(PT, bp, PAKSLEN);
-
- mpfree(PX);
- mpfree(PY);
- mpfree(PZ);
- mpfree(PT);
- mpfree(H);
-}
-
-void
-authpak_new(PAKpriv *p, Authkey *k, uchar y[PAKYLEN], int isclient)
-{
- mpint *PX,*PY,*PZ,*PT, *X, *Y;
- PAKcurve *c;
- uchar *bp;
-
- memset(p, 0, sizeof(PAKpriv));
- p->isclient = isclient != 0;
-
- X = mpnew(0);
- Y = mpnew(0);
-
- PX = mpnew(0);
- PY = mpnew(0);
- PZ = mpnew(0);
- PT = mpnew(0);
-
- PX->flags |= MPtimesafe;
- PY->flags |= MPtimesafe;
- PZ->flags |= MPtimesafe;
- PT->flags |= MPtimesafe;
-
- bp = k->pakhash + PAKPLEN*(p->isclient == 0);
- betomp(bp, PAKSLEN, PX), bp += PAKSLEN;
- betomp(bp, PAKSLEN, PY), bp += PAKSLEN;
- betomp(bp, PAKSLEN, PZ), bp += PAKSLEN;
- betomp(bp, PAKSLEN, PT);
-
- c = authpak_curve();
-
- X->flags |= MPtimesafe;
- mpnrand(c->P, genrandom, X);
-
- spake2ee_1(c->P,c->A,c->D, X, c->X,c->Y, PX,PY,PZ,PT, Y);
-
- mptober(X, p->x, PAKXLEN);
- mptober(Y, p->y, PAKYLEN);
-
- memmove(y, p->y, PAKYLEN);
-
- mpfree(PX);
- mpfree(PY);
- mpfree(PZ);
- mpfree(PT);
-
- mpfree(X);
- mpfree(Y);
-}
-
-int
-authpak_finish(PAKpriv *p, Authkey *k, uchar y[PAKYLEN])
-{
- static char info[] = "Plan 9 AuthPAK key";
- uchar *bp, z[PAKSLEN], salt[SHA2_256dlen];
- mpint *PX,*PY,*PZ,*PT, *X, *Y, *Z, *ok;
- DigestState *s;
- PAKcurve *c;
- int ret;
-
- X = mpnew(0);
- Y = mpnew(0);
- Z = mpnew(0);
- ok = mpnew(0);
-
- PX = mpnew(0);
- PY = mpnew(0);
- PZ = mpnew(0);
- PT = mpnew(0);
-
- PX->flags |= MPtimesafe;
- PY->flags |= MPtimesafe;
- PZ->flags |= MPtimesafe;
- PT->flags |= MPtimesafe;
-
- bp = k->pakhash + PAKPLEN*(p->isclient != 0);
- betomp(bp, PAKSLEN, PX), bp += PAKSLEN;
- betomp(bp, PAKSLEN, PY), bp += PAKSLEN;
- betomp(bp, PAKSLEN, PZ), bp += PAKSLEN;
- betomp(bp, PAKSLEN, PT);
-
- Z->flags |= MPtimesafe;
- X->flags |= MPtimesafe;
- betomp(p->x, PAKXLEN, X);
-
- betomp(y, PAKYLEN, Y);
-
- c = authpak_curve();
- spake2ee_2(c->P,c->A,c->D, PX,PY,PZ,PT, X, Y, ok, Z);
-
- if(mpcmp(ok, mpzero) == 0){
- ret = -1;
- goto out;
- }
-
- mptober(Z, z, sizeof(z));
-
- s = sha2_256(p->isclient ? p->y : y, PAKYLEN, nil, nil);
- sha2_256(p->isclient ? y : p->y, PAKYLEN, salt, s);
-
- hkdf_x( salt, SHA2_256dlen,
- (uchar*)info, sizeof(info)-1,
- z, sizeof(z),
- k->pakkey, PAKKEYLEN,
- hmac_sha2_256, SHA2_256dlen);
-
- ret = 0;
-out:
- memset(z, 0, sizeof(z));
- memset(p, 0, sizeof(PAKpriv));
-
- mpfree(PX);
- mpfree(PY);
- mpfree(PZ);
- mpfree(PT);
-
- mpfree(X);
- mpfree(Y);
- mpfree(Z);
- mpfree(ok);
-
- return ret;
-}
--- a/libauthsrv/convA2M.c
+++ /dev/null
@@ -1,36 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <authsrv.h>
-
-extern int form1B2M(char *ap, int n, uchar key[32]);
-
-int
-convA2M(Authenticator *f, char *ap, int n, Ticket *t)
-{
- uchar *p;
-
- if(n < 1+CHALLEN)
- return 0;
-
- p = (uchar*)ap;
- *p++ = f->num;
- memmove(p, f->chal, CHALLEN), p += CHALLEN;
- switch(t->form){
- case 0:
- if(n < 1+CHALLEN+4)
- return 0;
-
- memset(p, 0, 4), p += 4; /* unused id field */
- n = p - (uchar*)ap;
- encrypt(t->key, ap, n);
- return n;
- case 1:
- if(n < 12+CHALLEN+NONCELEN+16)
- return 0;
-
- memmove(p, f->rand, NONCELEN), p += NONCELEN;
- return form1B2M(ap, (char*)p - ap, t->key);
- }
-
- return 0;
-}
--- a/libauthsrv/convM2A.c
+++ /dev/null
@@ -1,36 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <authsrv.h>
-
-extern int form1M2B(char *ap, int n, uchar key[32]);
-
-int
-convM2A(char *ap, int n, Authenticator *f, Ticket *t)
-{
- uchar buf[MAXAUTHENTLEN], *p;
- int m;
-
- memset(f, 0, sizeof(Authenticator));
- if(t->form == 0){
- m = 1+CHALLEN+4;
- if(n < m)
- return -m;
- memmove(buf, ap, m);
- decrypt(t->key, buf, m);
- } else {
- m = 12+CHALLEN+NONCELEN+16;
- if(n < m)
- return -m;
- memmove(buf, ap, m);
- if(form1M2B((char*)buf, m, t->key) < 0)
- return m;
- }
- p = buf;
- f->num = *p++;
- memmove(f->chal, p, CHALLEN);
- p += CHALLEN;
- if(t->form == 1)
- memmove(f->rand, p, NONCELEN);
-
- return m;
-}
--- a/libauthsrv/convM2PR.c
+++ /dev/null
@@ -1,39 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <authsrv.h>
-
-extern int form1M2B(char *ap, int n, uchar key[32]);
-
-int
-convM2PR(char *ap, int n, Passwordreq *f, Ticket *t)
-{
- uchar *p, buf[MAXPASSREQLEN];
- int m;
-
- memset(f, 0, sizeof(Passwordreq));
- if(t->form == 0){
- m = 1+2*PASSWDLEN+1+SECRETLEN;
- if(n < m)
- return -m;
- memmove(buf, ap, m);
- decrypt(t->key, buf, m);
- } else {
- m = 12+2*PASSWDLEN+1+SECRETLEN+16;
- if(n < m)
- return -m;
- memmove(buf, ap, m);
- if(form1M2B((char*)buf, m, t->key) < 0)
- return m;
- }
- p = buf;
- f->num = *p++;
- memmove(f->old, p, PASSWDLEN), p += PASSWDLEN;
- memmove(f->new, p, PASSWDLEN), p += PASSWDLEN;
- f->changesecret = *p++;
- memmove(f->secret, p, SECRETLEN);
- f->old[PASSWDLEN-1] = 0;
- f->new[PASSWDLEN-1] = 0;
- f->secret[SECRETLEN-1] = 0;
-
- return m;
-}
--- a/libauthsrv/convM2T.c
+++ /dev/null
@@ -1,51 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <authsrv.h>
-
-extern int form1check(char *ap, int n);
-extern int form1M2B(char *ap, int n, uchar key[32]);
-
-int
-convM2T(char *ap, int n, Ticket *f, Authkey *k)
-{
- uchar buf[MAXTICKETLEN], *p;
- int m;
-
- if(f != nil)
- memset(f, 0, sizeof(Ticket));
-
- if(n < 8)
- return -8;
-
- if(form1check(ap, n) < 0){
- m = 1+CHALLEN+2*ANAMELEN+DESKEYLEN;
- if(n < m)
- return -m;
- if(f == nil || k == nil)
- return m;
- f->form = 0;
- memmove(buf, ap, m);
- decrypt(k->des, buf, m);
- } else {
- m = 12+CHALLEN+2*ANAMELEN+NONCELEN+16;
- if(n < m)
- return -m;
- if(f == nil || k == nil)
- return m;
- f->form = 1;
- memmove(buf, ap, m);
- if(form1M2B((char*)buf, m, k->pakkey) < 0)
- return m;
- }
- p = buf;
- f->num = *p++;
- memmove(f->chal, p, CHALLEN), p += CHALLEN;
- memmove(f->cuid, p, ANAMELEN), p += ANAMELEN;
- memmove(f->suid, p, ANAMELEN), p += ANAMELEN;
- memmove(f->key, p, f->form == 0 ? DESKEYLEN : NONCELEN);
-
- f->cuid[ANAMELEN-1] = 0;
- f->suid[ANAMELEN-1] = 0;
-
- return m;
-}
--- a/libauthsrv/convM2TR.c
+++ /dev/null
@@ -1,29 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <authsrv.h>
-
-int
-convM2TR(char *ap, int n, Ticketreq *f)
-{
- uchar *p;
-
- memset(f, 0, sizeof(Ticketreq));
- if(n < TICKREQLEN)
- return -TICKREQLEN;
-
- p = (uchar*)ap;
- f->type = *p++;
- memmove(f->authid, p, ANAMELEN), p += ANAMELEN;
- memmove(f->authdom, p, DOMLEN), p += DOMLEN;
- memmove(f->chal, p, CHALLEN), p += CHALLEN;
- memmove(f->hostid, p, ANAMELEN), p += ANAMELEN;
- memmove(f->uid, p, ANAMELEN), p += ANAMELEN;
-
- f->authid[ANAMELEN-1] = 0;
- f->authdom[DOMLEN-1] = 0;
- f->hostid[ANAMELEN-1] = 0;
- f->uid[ANAMELEN-1] = 0;
- n = p - (uchar*)ap;
-
- return n;
-}
--- a/libauthsrv/convPR2M.c
+++ /dev/null
@@ -1,34 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <authsrv.h>
-
-extern int form1B2M(char *ap, int n, uchar key[32]);
-
-int
-convPR2M(Passwordreq *f, char *ap, int n, Ticket *t)
-{
- uchar *p;
-
- if(n < 1+2*PASSWDLEN+1+SECRETLEN)
- return 0;
-
- p = (uchar*)ap;
- *p++ = f->num;
- memmove(p, f->old, PASSWDLEN), p += PASSWDLEN;
- memmove(p, f->new, PASSWDLEN), p += PASSWDLEN;
- *p++ = f->changesecret;
- memmove(p, f->secret, SECRETLEN), p += SECRETLEN;
- switch(t->form){
- case 0:
- n = p - (uchar*)ap;
- encrypt(t->key, ap, n);
- return n;
- case 1:
- if(n < 12+2*PASSWDLEN+1+SECRETLEN+16)
- return 0;
- return form1B2M(ap, p - (uchar*)ap, t->key);
- }
-
- return 0;
-}
-
--- a/libauthsrv/convT2M.c
+++ /dev/null
@@ -1,39 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <authsrv.h>
-#include <libsec.h>
-
-extern int form1B2M(char *ap, int n, uchar key[32]);
-
-int
-convT2M(Ticket *f, char *ap, int n, Authkey *key)
-{
- uchar *p;
-
- if(n < 1+CHALLEN+2*ANAMELEN)
- return 0;
-
- p = (uchar*)ap;
- *p++ = f->num;
- memmove(p, f->chal, CHALLEN), p += CHALLEN;
- memmove(p, f->cuid, ANAMELEN), p += ANAMELEN;
- memmove(p, f->suid, ANAMELEN), p += ANAMELEN;
- switch(f->form){
- case 0:
- if(n < 1+CHALLEN+2*ANAMELEN+DESKEYLEN)
- return 0;
-
- memmove(p, f->key, DESKEYLEN), p += DESKEYLEN;
- n = p - (uchar*)ap;
- encrypt(key->des, ap, n);
- return n;
- case 1:
- if(n < 12+CHALLEN+2*ANAMELEN+NONCELEN+16)
- return 0;
-
- memmove(p, f->key, NONCELEN), p += NONCELEN;
- return form1B2M(ap, p - (uchar*)ap, key->pakkey);
- }
-
- return 0;
-}
--- a/libauthsrv/convTR2M.c
+++ /dev/null
@@ -1,23 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <authsrv.h>
-
-int
-convTR2M(Ticketreq *f, char *ap, int n)
-{
- uchar *p;
-
- if(n < TICKREQLEN)
- return 0;
-
- p = (uchar*)ap;
- *p++ = f->type;
- memmove(p, f->authid, ANAMELEN), p += ANAMELEN;
- memmove(p, f->authdom, DOMLEN), p += DOMLEN;
- memmove(p, f->chal, CHALLEN), p += CHALLEN;
- memmove(p, f->hostid, ANAMELEN), p += ANAMELEN;
- memmove(p, f->uid, ANAMELEN), p += ANAMELEN;
- n = p - (uchar*)ap;
-
- return n;
-}
--- a/libauthsrv/decaf.mpc
+++ /dev/null
@@ -1,130 +1,0 @@
-void decaf_neg(mpint *p, mpint *n, mpint *r){
- mpint *m = mpnew(0);
- mpmodsub(mpzero, r, p, m);
- mpint *tmp1 = mpnew(0);
- mpsub(p, mpone, tmp1);
- mpright(tmp1, 1, tmp1);
- mpsel(-mpcmp(n, tmp1) >> (sizeof(int)*8-1), m, r, r);
- mpfree(tmp1);
- mpfree(m);
- }
-void decaf_encode(mpint *p, mpint *a, mpint *d, mpint *X, mpint *Y, mpint *Z, mpint *T, mpint *s){
- mpint *u = mpnew(0);
- mpint *r = mpnew(0);
- mpint *tmp1 = mpnew(0);
- mpint *tmp2 = mpnew(0);
- mpint *tmp3 = mpnew(0);
- mpmodsub(a, d, p, tmp3);
- mpint *tmp4 = mpnew(0);
- mpmodadd(Z, Y, p, tmp4);
- mpmodmul(tmp3, tmp4, p, tmp2);
- mpfree(tmp3);
- mpfree(tmp4);
- tmp4 = mpnew(0);
- mpmodsub(Z, Y, p, tmp4);
- mpmodmul(tmp2, tmp4, p, tmp1);
- mpfree(tmp2);
- mpfree(tmp4);
- misqrt(tmp1, p, r);
- mpfree(tmp1);
- tmp1 = mpnew(0);
- mpmodsub(a, d, p, tmp1);
- mpmodmul(tmp1, r, p, u);
- mpfree(tmp1);
- tmp1 = mpnew(0);
- tmp4 = mpnew(0);
- mpmodadd(u, u, p, tmp4); // 2*u
- mpmodmul(tmp4, Z, p, tmp1);
- mpfree(tmp4);
- mpmodsub(mpzero, tmp1, p, tmp1);
- decaf_neg(p, tmp1, r);
- mpfree(tmp1);
- tmp1 = mpnew(0);
- tmp4 = mpnew(0);
- tmp2 = mpnew(0);
- tmp3 = mpnew(0);
- mpmodmul(a, Z, p, tmp3);
- mpmodmul(tmp3, X, p, tmp2);
- mpfree(tmp3);
- tmp3 = mpnew(0);
- mpint *tmp5 = mpnew(0);
- mpmodmul(d, Y, p, tmp5);
- mpmodmul(tmp5, T, p, tmp3);
- mpfree(tmp5);
- mpmodsub(tmp2, tmp3, p, tmp2);
- mpfree(tmp3);
- mpmodmul(r, tmp2, p, tmp4);
- mpfree(tmp2);
- mpmodadd(tmp4, Y, p, tmp4);
- mpmodmul(u, tmp4, p, tmp1);
- mpfree(tmp4);
- tmp4 = mpnew(0);
- mpinvert(a, p, tmp4);
- mpmodmul(tmp1, tmp4, p, s);
- mpfree(tmp4);
- mpfree(tmp1);
- decaf_neg(p, s, s);
- mpfree(u);
- mpfree(r);
- }
-void decaf_decode(mpint *p, mpint *a, mpint *d, mpint *s, mpint *ok, mpint *X, mpint *Y, mpint *Z, mpint *T){
- mpint *w = mpnew(0);
- mpint *v = mpnew(0);
- mpint *u = mpnew(0);
- mpint *ss = mpnew(0);
- mpint *tmp1 = mpnew(0);
- mpsub(p, mpone, tmp1);
- mpright(tmp1, 1, tmp1);
- if(mpcmp(s, tmp1) > 0){
- mpassign(mpzero, ok);
- }else{
- mpmodmul(s, s, p, ss);
- mpmodmul(a, ss, p, Z);
- mpmodadd(mpone, Z, p, Z);
- mpmodmul(Z, Z, p, u);
- mpint *tmp2 = mpnew(0);
- mpint *tmp3 = mpnew(0);
- mpint *tmp4 = mpnew(0);
- uitomp(4UL, tmp4);
- mpmodmul(tmp4, d, p, tmp3);
- mpfree(tmp4);
- mpmodmul(tmp3, ss, p, tmp2);
- mpfree(tmp3);
- mpmodsub(u, tmp2, p, u);
- mpfree(tmp2);
- mpmodmul(u, ss, p, v);
- if(mpcmp(v, mpzero) == 0){
- mpassign(mpone, ok);
- }else{
- msqrt(v, p, ok);
- if(mpcmp(ok, mpzero) != 0){
- mpinvert(ok, p, v);
- mpassign(mpone, ok);
- }
- }
- if(mpcmp(ok, mpzero) != 0){
- mpint *tmp5 = mpnew(0);
- mpmodmul(u, v, p, tmp5);
- decaf_neg(p, tmp5, v);
- mpfree(tmp5);
- tmp5 = mpnew(0);
- mpmodmul(v, s, p, tmp5);
- mpint *tmp6 = mpnew(0);
- mpmodsub(mptwo, Z, p, tmp6);
- mpmodmul(tmp5, tmp6, p, w);
- mpfree(tmp5);
- mpfree(tmp6);
- if(mpcmp(s, mpzero) == 0){
- mpmodadd(w, mpone, p, w);
- }
- mpmodadd(s, s, p, X); // 2*s
- mpmodmul(w, Z, p, Y);
- mpmodmul(w, X, p, T);
- }
- }
- mpfree(tmp1);
- mpfree(w);
- mpfree(v);
- mpfree(u);
- mpfree(ss);
- }
--- a/libauthsrv/ed448.mpc
+++ /dev/null
@@ -1,8 +1,0 @@
-void ed448_curve(mpint *p, mpint *a, mpint *d, mpint *x, mpint *y){
- strtomp("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", nil, 16, p);
- mpassign(mpone, a);
- uitomp(39081UL, d);
- d->sign = -1;
- strtomp("297EA0EA2692FF1B4FAFF46098453A6A26ADF733245F065C3C59D0709CECFA96147EAAF3932D94C63D96C170033F4BA0C7F0DE840AED939F", nil, 16, x);
- uitomp(19UL, y);
- }
--- a/libauthsrv/edwards.mpc
+++ /dev/null
@@ -1,98 +1,0 @@
-void edwards_add(mpint *p, mpint *a, mpint *d, mpint *X1, mpint *Y1, mpint *Z1, mpint *T1, mpint *X2, mpint *Y2, mpint *Z2, mpint *T2, mpint *X3, mpint *Y3, mpint *Z3, mpint *T3){
- mpint *H = mpnew(0);
- mpint *G = mpnew(0);
- mpint *F = mpnew(0);
- mpint *E = mpnew(0);
- mpint *D = mpnew(0);
- mpint *C = mpnew(0);
- mpint *B = mpnew(0);
- mpint *A = mpnew(0);
- mpmodmul(X1, X2, p, A);
- mpmodmul(Y1, Y2, p, B);
- mpint *tmp1 = mpnew(0);
- mpmodmul(d, T1, p, tmp1);
- mpmodmul(tmp1, T2, p, C);
- mpfree(tmp1);
- mpmodmul(Z1, Z2, p, D);
- tmp1 = mpnew(0);
- mpmodadd(X1, Y1, p, tmp1);
- mpint *tmp2 = mpnew(0);
- mpmodadd(X2, Y2, p, tmp2);
- mpmodmul(tmp1, tmp2, p, E);
- mpfree(tmp1);
- mpfree(tmp2);
- mpmodsub(E, A, p, E);
- mpmodsub(E, B, p, E);
- mpmodsub(D, C, p, F);
- mpmodadd(D, C, p, G);
- mpmodmul(a, A, p, H);
- mpmodsub(B, H, p, H);
- mpmodmul(E, F, p, X3);
- mpmodmul(G, H, p, Y3);
- mpmodmul(F, G, p, Z3);
- mpmodmul(E, H, p, T3);
- mpfree(H);
- mpfree(G);
- mpfree(F);
- mpfree(E);
- mpfree(D);
- mpfree(C);
- mpfree(B);
- mpfree(A);
- }
-void edwards_sel(mpint *s, mpint *X1, mpint *Y1, mpint *Z1, mpint *T1, mpint *X2, mpint *Y2, mpint *Z2, mpint *T2, mpint *X3, mpint *Y3, mpint *Z3, mpint *T3){
- mpsel(mpcmp(s, mpzero), X1, X2, X3);
- mpsel(mpcmp(s, mpzero), Y1, Y2, Y3);
- mpsel(mpcmp(s, mpzero), Z1, Z2, Z3);
- mpsel(mpcmp(s, mpzero), T1, T2, T3);
- }
-void edwards_new(mpint *x, mpint *y, mpint *z, mpint *t, mpint *X, mpint *Y, mpint *Z, mpint *T){
- mpassign(x, X);
- mpassign(y, Y);
- mpassign(z, Z);
- mpassign(t, T);
- }
-void edwards_scale(mpint *p, mpint *a, mpint *d, mpint *s, mpint *X1, mpint *Y1, mpint *Z1, mpint *T1, mpint *X3, mpint *Y3, mpint *Z3, mpint *T3){
- mpint *j = mpnew(0);
- mpint *k = mpnew(0);
- mpint *T4 = mpnew(0);
- mpint *Z4 = mpnew(0);
- mpint *Y4 = mpnew(0);
- mpint *X4 = mpnew(0);
- mpint *T2 = mpnew(0);
- mpint *Z2 = mpnew(0);
- mpint *Y2 = mpnew(0);
- mpint *X2 = mpnew(0);
- edwards_new(X1, Y1, Z1, T1, X2, Y2, Z2, T2);
- edwards_new(mpzero, mpone, mpone, mpzero, X4, Y4, Z4, T4);
- mpint *tmp1 = mpnew(0);
- mpmod(s, mptwo, tmp1);
- edwards_sel(tmp1, X2, Y2, Z2, T2, X4, Y4, Z4, T4, X3, Y3, Z3, T3);
- mpfree(tmp1);
- mpright(s, 1, k);
- mpright(p, 1, j);
- for(;;){
- if(mpcmp(j, mpzero) != 0){
- edwards_add(p, a, d, X2, Y2, Z2, T2, X2, Y2, Z2, T2, X2, Y2, Z2, T2);
- edwards_add(p, a, d, X2, Y2, Z2, T2, X3, Y3, Z3, T3, X4, Y4, Z4, T4);
- mpint *tmp2 = mpnew(0);
- mpmod(k, mptwo, tmp2);
- edwards_sel(tmp2, X4, Y4, Z4, T4, X3, Y3, Z3, T3, X3, Y3, Z3, T3);
- mpfree(tmp2);
- mpright(k, 1, k);
- mpright(j, 1, j);
- }else{
- break;
- }
- }
- mpfree(j);
- mpfree(k);
- mpfree(T4);
- mpfree(Z4);
- mpfree(Y4);
- mpfree(X4);
- mpfree(T2);
- mpfree(Z2);
- mpfree(Y2);
- mpfree(X2);
- }
--- a/libauthsrv/elligator2.mpc
+++ /dev/null
@@ -1,129 +1,0 @@
-void elligator2(mpint *p, mpint *a, mpint *d, mpint *n, mpint *r0, mpint *X, mpint *Y, mpint *Z, mpint *T){
- mpint *t = mpnew(0);
- mpint *s = mpnew(0);
- mpint *e = mpnew(0);
- mpint *c = mpnew(0);
- mpint *ND = mpnew(0);
- mpint *N = mpnew(0);
- mpint *D = mpnew(0);
- mpint *r = mpnew(0);
- mpint *tmp1 = mpnew(0);
- mpmodmul(n, r0, p, tmp1);
- mpmodmul(tmp1, r0, p, r);
- mpfree(tmp1);
- tmp1 = mpnew(0);
- mpmodmul(d, r, p, tmp1);
- mpmodadd(tmp1, a, p, tmp1);
- mpmodsub(tmp1, d, p, tmp1);
- mpint *tmp2 = mpnew(0);
- mpmodmul(d, r, p, tmp2);
- mpint *tmp3 = mpnew(0);
- mpmodmul(a, r, p, tmp3);
- mpmodsub(tmp2, tmp3, p, tmp2);
- mpfree(tmp3);
- mpmodsub(tmp2, d, p, tmp2);
- mpmodmul(tmp1, tmp2, p, D);
- mpfree(tmp1);
- mpfree(tmp2);
- tmp2 = mpnew(0);
- mpmodadd(r, mpone, p, tmp2);
- tmp1 = mpnew(0);
- mpmodadd(d, d, p, tmp1); // 2*d
- mpmodsub(a, tmp1, p, tmp1);
- mpmodmul(tmp2, tmp1, p, N);
- mpfree(tmp2);
- mpfree(tmp1);
- mpmodmul(N, D, p, ND);
- if(mpcmp(ND, mpzero) == 0){
- mpassign(mpone, c);
- mpassign(mpzero, e);
- }else{
- msqrt(ND, p, e);
- if(mpcmp(e, mpzero) != 0){
- mpassign(mpone, c);
- mpinvert(e, p, e);
- }else{
- mpmodsub(mpzero, mpone, p, c);
- mpint *tmp4 = mpnew(0);
- mpmodmul(n, r0, p, tmp4);
- mpint *tmp5 = mpnew(0);
- mpint *tmp6 = mpnew(0);
- mpmodmul(n, ND, p, tmp6);
- misqrt(tmp6, p, tmp5);
- mpfree(tmp6);
- mpmodmul(tmp4, tmp5, p, e);
- mpfree(tmp4);
- mpfree(tmp5);
- }
- }
- tmp1 = mpnew(0);
- mpmodmul(c, N, p, tmp1);
- mpmodmul(tmp1, e, p, s);
- mpfree(tmp1);
- tmp1 = mpnew(0);
- tmp2 = mpnew(0);
- mpmodmul(c, N, p, tmp2);
- tmp3 = mpnew(0);
- mpmodsub(r, mpone, p, tmp3);
- mpmodmul(tmp2, tmp3, p, tmp1);
- mpfree(tmp2);
- mpfree(tmp3);
- tmp3 = mpnew(0);
- tmp2 = mpnew(0);
- mpmodadd(d, d, p, tmp2); // 2*d
- mpmodsub(a, tmp2, p, tmp2);
- mpmodmul(tmp2, e, p, tmp3);
- mpfree(tmp2);
- mpmodmul(tmp3, tmp3, p, tmp3);
- mpmodmul(tmp1, tmp3, p, t);
- mpfree(tmp1);
- mpfree(tmp3);
- mpmodsub(mpzero, t, p, t);
- mpmodsub(t, mpone, p, t);
- tmp3 = mpnew(0);
- mpmodadd(s, s, p, tmp3); // 2*s
- mpmodmul(tmp3, t, p, X);
- mpfree(tmp3);
- tmp3 = mpnew(0);
- tmp1 = mpnew(0);
- mpmodmul(a, s, p, tmp1);
- mpmodmul(tmp1, s, p, tmp3);
- mpfree(tmp1);
- mpmodsub(mpone, tmp3, p, tmp3);
- tmp1 = mpnew(0);
- tmp2 = mpnew(0);
- mpmodmul(a, s, p, tmp2);
- mpmodmul(tmp2, s, p, tmp1);
- mpfree(tmp2);
- mpmodadd(mpone, tmp1, p, tmp1);
- mpmodmul(tmp3, tmp1, p, Y);
- mpfree(tmp3);
- mpfree(tmp1);
- tmp1 = mpnew(0);
- tmp3 = mpnew(0);
- mpmodmul(a, s, p, tmp3);
- mpmodmul(tmp3, s, p, tmp1);
- mpfree(tmp3);
- mpmodadd(mpone, tmp1, p, tmp1);
- mpmodmul(tmp1, t, p, Z);
- mpfree(tmp1);
- tmp1 = mpnew(0);
- mpmodadd(s, s, p, tmp1); // 2*s
- tmp3 = mpnew(0);
- tmp2 = mpnew(0);
- mpmodmul(a, s, p, tmp2);
- mpmodmul(tmp2, s, p, tmp3);
- mpfree(tmp2);
- mpmodsub(mpone, tmp3, p, tmp3);
- mpmodmul(tmp1, tmp3, p, T);
- mpfree(tmp1);
- mpfree(tmp3);
- mpfree(t);
- mpfree(s);
- mpfree(e);
- mpfree(c);
- mpfree(ND);
- mpfree(N);
- mpfree(D);
- mpfree(r);
- }
--- a/libauthsrv/form1.c
+++ /dev/null
@@ -1,90 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <authsrv.h>
-#include <libsec.h>
-
-/*
- * new ticket format: the reply protector/type is replaced by a
- * 8 byte signature and a 4 byte counter forming the 12 byte
- * nonce for chacha20/poly1305 encryption. a 16 byte poly1305
- * authentication tag is appended for message authentication.
- * the counter is needed for the AuthPass message which uses
- * the same key for several messages.
- */
-
-static struct {
- char num;
- char sig[8];
-} form1sig[] = {
- AuthPass, "form1 PR", /* password change request encrypted with ticket key */
- AuthTs, "form1 Ts", /* ticket encrypted with server's key */
- AuthTc, "form1 Tc", /* ticket encrypted with client's key */
- AuthAs, "form1 As", /* server generated authenticator */
- AuthAc, "form1 Ac", /* client generated authenticator */
- AuthTp, "form1 Tp", /* ticket encrypted with client's key for password change */
- AuthHr, "form1 Hr", /* http reply */
-};
-
-int
-form1check(char *ap, int n)
-{
- if(n < 8)
- return -1;
-
- for(n=0; n<nelem(form1sig); n++)
- if(memcmp(form1sig[n].sig, ap, 8) == 0)
- return form1sig[n].num;
-
- return -1;
-}
-
-int
-form1B2M(char *ap, int n, uchar key[32])
-{
- static u32int counter;
- Chachastate s;
- uchar *p;
- int i;
-
- for(i=nelem(form1sig)-1; i>=0; i--)
- if(form1sig[i].num == *ap)
- break;
- if(i < 0)
- abort();
-
- p = (uchar*)ap + 12;
- memmove(p, ap+1, --n);
-
- /* nonce[12] = sig[8] | counter[4] */
- memmove(ap, form1sig[i].sig, 8);
- i = counter++;
- ap[8] = i, ap[9] = i>>8, ap[10] = i>>16, ap[11] = i>>24;
-
- setupChachastate(&s, key, 32, (uchar*)ap, 12, 20);
- ccpoly_encrypt(p, n, nil, 0, p+n, &s);
- return 12+16 + n;
-}
-
-int
-form1M2B(char *ap, int n, uchar key[32])
-{
- Chachastate s;
- uchar *p;
- int num;
-
- num = form1check(ap, n);
- if(num < 0)
- return -1;
- n -= 12+16;
- if(n <= 0)
- return -1;
-
- p = (uchar*)ap + 12;
- setupChachastate(&s, key, 32, (uchar*)ap, 12, 20);
- if(ccpoly_decrypt(p, n, nil, 0, p+n, &s))
- return -1;
-
- memmove(ap+1, p, n);
- ap[0] = num;
- return n+1;
-}
--- a/libauthsrv/msqrt.mpc
+++ /dev/null
@@ -1,149 +1,0 @@
-void legendresymbol(mpint *a, mpint *p, mpint *r){
- mpint *pm1 = mpnew(0);
- mpsub(p, mpone, pm1);
- mpright(pm1, 1, r);
- mpexp(a, r, p, r);
- if(mpcmp(r, pm1) == 0){
- mpassign(mpone, r);
- r->sign = -1;
- }
- mpfree(pm1);
- }
-void msqrt(mpint *a, mpint *p, mpint *r){
- mpint *gs = mpnew(0);
- mpint *m = mpnew(0);
- mpint *t = mpnew(0);
- mpint *g = mpnew(0);
- mpint *b = mpnew(0);
- mpint *x = mpnew(0);
- mpint *n = mpnew(0);
- mpint *s = mpnew(0);
- mpint *e = mpnew(0);
- mpint *tmp1 = mpnew(0);
- legendresymbol(a, p, tmp1);
- if(mpcmp(tmp1, mpone) != 0){
- mpassign(mpzero, r);
- }else{
- if(mpcmp(a, mpzero) == 0){
- mpassign(mpzero, r);
- }else{
- if(mpcmp(p, mptwo) == 0){
- mpassign(a, r);
- }else{
- mpint *tmp2 = mpnew(0);
- uitomp(4UL, tmp2);
- mpmod(p, tmp2, tmp2);
- mpint *tmp3 = mpnew(0);
- uitomp(3UL, tmp3);
- if(mpcmp(tmp2, tmp3) == 0){
- mpadd(p, mpone, e);
- mpright(e, 2, e);
- mpexp(a, e, p, r);
- }else{
- mpsub(p, mpone, s);
- mpassign(mpzero, e);
- for(;;){
- mpint *tmp4 = mpnew(0);
- mpmod(s, mptwo, tmp4);
- if(mpcmp(tmp4, mpzero) == 0){
- mpright(s, 1, s);
- mpadd(e, mpone, e);
- }else{
- mpfree(tmp4);
- break;
- }
- mpfree(tmp4);
- }
- mpassign(mptwo, n);
- for(;;){
- mpint *tmp5 = mpnew(0);
- legendresymbol(n, p, tmp5);
- mpint *tmp6 = mpnew(0);
- mpassign(mpone, tmp6);
- tmp6->sign = -1;
- if(mpcmp(tmp5, tmp6) != 0){
- mpadd(n, mpone, n);
- }else{
- mpfree(tmp6);
- mpfree(tmp5);
- break;
- }
- mpfree(tmp5);
- mpfree(tmp6);
- }
- mpmodadd(s, mpone, p, x);
- mpright(x, 1, x);
- mpexp(a, x, p, x);
- mpexp(a, s, p, b);
- mpexp(n, s, p, g);
- for(;;){
- if(0 == 0){
- mpassign(b, t);
- mpassign(mpzero, m);
- for(;;){
- if(mpcmp(m, e) < 0){
- if(mpcmp(t, mpone) == 0){
- break;
- }
- mpmul(t, t, t);
- mpmod(t, p, t);
- mpadd(m, mpone, m);
- }else{
- break;
- }
- }
- if(mpcmp(m, mpzero) == 0){
- mpassign(x, r);
- break;
- }
- mpsub(e, m, t);
- mpsub(t, mpone, t);
- mpexp(mptwo, t, nil, t);
- mpexp(g, t, p, gs);
- mpmodmul(gs, gs, p, g);
- mpmodmul(x, gs, p, x);
- mpmodmul(b, g, p, b);
- mpassign(m, e);
- }else{
- break;
- }
- }
- }
- mpfree(tmp2);
- mpfree(tmp3);
- }
- }
- }
- mpfree(tmp1);
- mpfree(gs);
- mpfree(m);
- mpfree(t);
- mpfree(g);
- mpfree(b);
- mpfree(x);
- mpfree(n);
- mpfree(s);
- mpfree(e);
- }
-void misqrt(mpint *a, mpint *p, mpint *r){
- mpint *e = mpnew(0);
- mpint *tmp1 = mpnew(0);
- uitomp(4UL, tmp1);
- mpmod(p, tmp1, tmp1);
- mpint *tmp2 = mpnew(0);
- uitomp(3UL, tmp2);
- if(mpcmp(tmp1, tmp2) == 0){
- uitomp(3UL, e);
- mpsub(p, e, e);
- mpright(e, 2, e);
- mpexp(a, e, p, r);
- }else{
- msqrt(a, p, r);
- if(mpcmp(r, mpzero) != 0){
- mpinvert(r, p, r);
- }
- }
- mpfree(tmp1);
- mpfree(tmp2);
- mpfree(e);
- }
--- a/libauthsrv/nvcsum.c
+++ /dev/null
@@ -1,16 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <auth.h>
-
-uchar
-nvcsum(void *vmem, int n)
-{
- uchar *mem, sum;
- int i;
-
- sum = 9;
- mem = vmem;
- for(i = 0; i < n; i++)
- sum += mem[i];
- return sum;
-}
--- a/libauthsrv/passtokey.c
+++ /dev/null
@@ -1,48 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <authsrv.h>
-#include <libsec.h>
-
-void
-passtodeskey(char key[DESKEYLEN], char *p)
-{
- uchar buf[PASSWDLEN], *t;
- int i, n;
-
- memset(buf, ' ', 8);
- n = strlen(p);
- if(n >= sizeof(buf))
- n = sizeof(buf)-1;
- memmove(buf, p, n);
- buf[n] = 0;
- memset(key, 0, DESKEYLEN);
- t = buf;
- for(;;){
- for(i = 0; i < DESKEYLEN; i++)
- key[i] = (t[i] >> i) + (t[i+1] << (8 - (i+1)));
- if(n <= 8)
- return;
- n -= 8;
- t += 8;
- if(n < 8){
- t -= 8 - n;
- n = 8;
- }
- encrypt(key, t, 8);
- }
-}
-
-void
-passtoaeskey(uchar key[AESKEYLEN], char *p)
-{
- static char salt[] = "Plan 9 key derivation";
- pbkdf2_x((uchar*)p, strlen(p), (uchar*)salt, sizeof(salt)-1, 9001, key, AESKEYLEN, hmac_sha1, SHA1dlen);
-}
-
-void
-passtokey(Authkey *key, char *pw)
-{
- memset(key, 0, sizeof(Authkey));
- passtodeskey(key->des, pw);
- passtoaeskey(key->aes, pw);
-}
--- a/libauthsrv/readcons.c
+++ /dev/null
@@ -1,82 +1,0 @@
-#include <u.h>
-#include <libc.h>
-
-/*
- * prompt for a string with a possible default response
- */
-char*
-readcons(char *prompt, char *def, int raw)
-{
- int fdin, fdout, ctl, n;
- char *s, *p;
-
- s = p = nil;
- fdout = ctl = -1;
-
- if((fdin = open("/dev/cons", OREAD)) < 0)
- goto Out;
- if((fdout = open("/dev/cons", OWRITE)) < 0)
- goto Out;
-
- if(raw){
- if((ctl = open("/dev/consctl", OWRITE)) < 0)
- goto Out;
- write(ctl, "rawon", 5);
- }
-
- if(def != nil)
- fprint(fdout, "%s[%s]: ", prompt, def);
- else
- fprint(fdout, "%s: ", prompt);
-
- for(;;){
- n = p - s;
- if((n % 32) == 0){
- if((p = realloc(s, n+32)) == nil)
- break;
- s = p, p += n;
- }
-
- if(read(fdin, p, 1) <= 0 || *p == 0x7f)
- break;
-
- if(*p == '\n' || *p == '\r'){
- if(p == s && def != nil){
- free(s);
- s = strdup(def);
- } else
- *p = 0;
- if(raw)
- write(fdout, "\n", 1);
- goto Out;
- } else if(*p == '\b') {
- while(p > s && (p[-1] & 0xc0) == 0x80)
- *p-- = 0;
- if(p > s)
- *p-- = 0;
- } else if(*p == 0x15) { /* ^U: line kill */
- if(def != nil)
- fprint(fdout, "\n%s[%s]: ", prompt, def);
- else
- fprint(fdout, "\n%s: ", prompt);
- while(p > s)
- *p-- = 0;
- } else if((*p & 0xff) >= ' ')
- p++;
- }
- free(s);
- s = nil;
- if(raw)
- write(fdout, "\n", 1);
-Out:
- if(ctl >= 0){
- write(ctl, "rawoff", 6);
- close(ctl);
- }
- if(fdin >= 0)
- close(fdin);
- if(fdout >= 0)
- close(fdout);
-
- return s;
-}
--- a/libauthsrv/readnvram.c
+++ /dev/null
@@ -1,419 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <authsrv.h>
-
-static long finddosfile(int, char*);
-
-static int
-check(void *x, int len, uchar sum, char *msg)
-{
- if(nvcsum(x, len) == sum)
- return 0;
- memset(x, 0, len);
- fprint(2, "%s\n", msg);
- return 1;
-}
-
-/*
- * get key info out of nvram. since there isn't room in the PC's nvram use
- * a disk partition there.
- */
-static struct {
- char *cputype;
- char *file;
- int off;
- int len;
-} nvtab[] = {
- "sparc", "#r/nvram", 1024+850, sizeof(Nvrsafe),
- "pc", "#S/sdC0/nvram", 0, sizeof(Nvrsafe),
- "pc", "#S/sdC0/9fat", -1, sizeof(Nvrsafe),
- "pc", "#S/sdC1/nvram", 0, sizeof(Nvrsafe),
- "pc", "#S/sdC1/9fat", -1, sizeof(Nvrsafe),
- "pc", "#S/sdD0/nvram", 0, sizeof(Nvrsafe),
- "pc", "#S/sdD0/9fat", -1, sizeof(Nvrsafe),
- "pc", "#S/sdE0/nvram", 0, sizeof(Nvrsafe),
- "pc", "#S/sdE0/9fat", -1, sizeof(Nvrsafe),
- "pc", "#S/sdF0/nvram", 0, sizeof(Nvrsafe),
- "pc", "#S/sdF0/9fat", -1, sizeof(Nvrsafe),
- "pc", "#S/sd00/nvram", 0, sizeof(Nvrsafe),
- "pc", "#S/sd00/9fat", -1, sizeof(Nvrsafe),
- "pc", "#S/sd01/nvram", 0, sizeof(Nvrsafe),
- "pc", "#S/sd01/9fat", -1, sizeof(Nvrsafe),
- "pc", "#S/sd10/nvram", 0, sizeof(Nvrsafe),
- "pc", "#S/sd10/9fat", -1, sizeof(Nvrsafe),
- "pc", "#f/fd0disk", -1, 512, /* 512: #f requires whole sector reads */
- "pc", "#f/fd1disk", -1, 512,
- "mips", "#r/nvram", 1024+900, sizeof(Nvrsafe),
- "power", "#F/flash/flash0", 0x440000, sizeof(Nvrsafe),
- "power", "#F/flash/flash", 0x440000, sizeof(Nvrsafe),
- "power", "#r/nvram", 4352, sizeof(Nvrsafe), /* OK for MTX-604e */
- "power", "/nvram", 0, sizeof(Nvrsafe), /* OK for Ucu */
- "arm", "#F/flash/flash0", 0x100000, sizeof(Nvrsafe),
- "arm", "#F/flash/flash", 0x100000, sizeof(Nvrsafe),
- "debug", "/tmp/nvram", 0, sizeof(Nvrsafe),
-};
-
-typedef struct {
- int fd;
- int safelen;
- vlong safeoff;
-} Nvrwhere;
-
-static char *nvrfile = nil, *cputype = nil;
-
-/* returns with *locp filled in and locp->fd open, if possible */
-static void
-findnvram(Nvrwhere *locp)
-{
- char *nvrlen, *nvroff, *v[2];
- int fd, i, safelen;
- vlong safeoff;
-
- if (nvrfile == nil)
- nvrfile = getenv("nvram");
- if (cputype == nil)
- cputype = getenv("cputype");
- if(cputype == nil)
- cputype = strdup("mips");
- if(strcmp(cputype, "386")==0 || strcmp(cputype, "amd64")==0 || strcmp(cputype, "alpha")==0) {
- free(cputype);
- cputype = strdup("pc");
- }
-
- fd = -1;
- safeoff = -1;
- safelen = -1;
- if(nvrfile != nil && *nvrfile != '\0'){
- /* accept device and device!file */
- i = gettokens(nvrfile, v, nelem(v), "!");
- if (i < 1) {
- i = 1;
- v[0] = "";
- v[1] = nil;
- }
- fd = open(v[0], ORDWR);
- if (fd < 0)
- fd = open(v[0], OREAD);
- safelen = sizeof(Nvrsafe);
- if(strstr(v[0], "/9fat") == nil)
- safeoff = 0;
- nvrlen = getenv("nvrlen");
- if(nvrlen != nil)
- safelen = strtol(nvrlen, 0, 0);
- nvroff = getenv("nvroff");
- if(nvroff != nil)
- if(strcmp(nvroff, "dos") == 0)
- safeoff = -1;
- else
- safeoff = strtoll(nvroff, 0, 0);
- if(safeoff < 0 && fd >= 0){
- safelen = 512;
- safeoff = finddosfile(fd, i == 2? v[1]: "plan9.nvr");
- if(safeoff < 0){ /* didn't find plan9.nvr? */
- close(fd);
- fd = -1;
- }
- }
- free(nvroff);
- free(nvrlen);
- }else
- for(i=0; i<nelem(nvtab); i++){
- if(strcmp(cputype, nvtab[i].cputype) != 0)
- continue;
- if((fd = open(nvtab[i].file, ORDWR)) < 0)
- continue;
- safeoff = nvtab[i].off;
- safelen = nvtab[i].len;
- if(safeoff == -1){
- safeoff = finddosfile(fd, "plan9.nvr");
- if(safeoff < 0){ /* didn't find plan9.nvr? */
- close(fd);
- fd = -1;
- continue;
- }
- }
- break;
- }
- locp->fd = fd;
- locp->safelen = safelen;
- locp->safeoff = safeoff;
-}
-
-static int
-ask(char *prompt, char *buf, int len, int raw)
-{
- char *s;
- int n;
-
- memset(buf, 0, len);
- for(;;){
- if((s = readcons(prompt, nil, raw)) == nil)
- return -1;
- if((n = strlen(s)) >= len)
- fprint(2, "%s longer than %d characters; try again\n", prompt, len-1);
- else {
- memmove(buf, s, n);
- memset(s, 0, n);
- free(s);
- return 0;
- }
- memset(s, 0, n);
- free(s);
- }
-}
-
-/*
- * get key info out of nvram. since there isn't room in the PC's nvram use
- * a disk partition there.
- */
-int
-readnvram(Nvrsafe *safep, int flag)
-{
- int err;
- char buf[512]; /* 512 for floppy i/o */
- Nvrsafe *safe;
- Nvrwhere loc;
-
- err = 0;
- safe = (Nvrsafe*)buf;
- memset(&loc, 0, sizeof loc);
- findnvram(&loc);
- if (loc.safelen < 0)
- loc.safelen = sizeof *safe;
- else if (loc.safelen > sizeof buf)
- loc.safelen = sizeof buf;
- if (loc.safeoff < 0) {
- fprint(2, "readnvram: couldn't find nvram\n");
- if(!(flag&NVwritemem))
- memset(safep, 0, sizeof(*safep));
- safe = safep;
- /*
- * allow user to type the data for authentication,
- * even if there's no nvram to store it in.
- */
- }
-
- if(flag&NVwritemem)
- safe = safep;
- else {
- memset(safep, 0, sizeof(*safep));
- if(loc.fd < 0
- || seek(loc.fd, loc.safeoff, 0) < 0
- || read(loc.fd, buf, loc.safelen) != loc.safelen){
- err = 1;
- if(flag&(NVwrite|NVwriteonerr))
- if(loc.fd < 0)
- fprint(2, "can't open %s: %r\n", nvrfile);
- else if (seek(loc.fd, loc.safeoff, 0) < 0)
- fprint(2, "can't seek %s to %lld: %r\n",
- nvrfile, loc.safeoff);
- else
- fprint(2, "can't read %d bytes from %s: %r\n",
- loc.safelen, nvrfile);
- /* start from scratch */
- memset(safep, 0, sizeof(*safep));
- safe = safep;
- }else{
- *safep = *safe; /* overwrite arg with data read */
- safe = safep;
-
- /* verify data read */
- err |= check(safe->machkey, DESKEYLEN, safe->machsum,
- "bad nvram des key");
- err |= check(safe->authid, ANAMELEN, safe->authidsum,
- "bad authentication id");
- err |= check(safe->authdom, DOMLEN, safe->authdomsum,
- "bad authentication domain");
- if(0){
- err |= check(safe->config, CONFIGLEN, safe->configsum,
- "bad secstore key");
- err |= check(safe->aesmachkey, AESKEYLEN, safe->aesmachsum,
- "bad nvram aes key");
- } else {
- if(nvcsum(safe->config, CONFIGLEN) != safe->configsum)
- memset(safe->config, 0, CONFIGLEN);
- if(nvcsum(safe->aesmachkey, AESKEYLEN) != safe->aesmachsum)
- memset(safe->aesmachkey, 0, AESKEYLEN);
- }
- if(err == 0)
- if(safe->authid[0]==0 || safe->authdom[0]==0){
- fprint(2, "empty nvram authid or authdom\n");
- err = 1;
- }
- }
- }
-
- if((flag&(NVwrite|NVwritemem)) || (err && (flag&NVwriteonerr))){
- if (!(flag&NVwritemem)) {
- char pass[PASSWDLEN];
- Authkey k;
-
- if(ask("authid", safe->authid, sizeof safe->authid, 0))
- goto Out;
- if(ask("authdom", safe->authdom, sizeof safe->authdom, 0))
- goto Out;
- if(ask("secstore key", safe->config, sizeof safe->config, 1))
- goto Out;
- if(ask("password", pass, sizeof pass, 1))
- goto Out;
- passtokey(&k, pass);
- memset(pass, 0, sizeof pass);
- memmove(safe->machkey, k.des, DESKEYLEN);
- memmove(safe->aesmachkey, k.aes, AESKEYLEN);
- memset(&k, 0, sizeof k);
- }
-
- safe->machsum = nvcsum(safe->machkey, DESKEYLEN);
- // safe->authsum = nvcsum(safe->authkey, DESKEYLEN);
- safe->configsum = nvcsum(safe->config, CONFIGLEN);
- safe->authidsum = nvcsum(safe->authid, sizeof safe->authid);
- safe->authdomsum = nvcsum(safe->authdom, sizeof safe->authdom);
- safe->aesmachsum = nvcsum(safe->aesmachkey, AESKEYLEN);
-
- *(Nvrsafe*)buf = *safe;
- if(loc.fd < 0
- || seek(loc.fd, loc.safeoff, 0) < 0
- || write(loc.fd, buf, loc.safelen) != loc.safelen){
- fprint(2, "can't write key to nvram: %r\n");
- err = 1;
- }else
- err = 0;
- }
-Out:
- if (loc.fd >= 0)
- close(loc.fd);
- return err? -1: 0;
-}
-
-typedef struct Dosboot Dosboot;
-struct Dosboot{
- uchar magic[3]; /* really an xx86 JMP instruction */
- uchar version[8];
- uchar sectsize[2];
- uchar clustsize;
- uchar nresrv[2];
- uchar nfats;
- uchar rootsize[2];
- uchar volsize[2];
- uchar mediadesc;
- uchar fatsize[2];
- uchar trksize[2];
- uchar nheads[2];
- uchar nhidden[4];
- uchar bigvolsize[4];
- uchar driveno;
- uchar reserved0;
- uchar bootsig;
- uchar volid[4];
- uchar label[11];
- uchar type[8];
-};
-#define GETSHORT(p) (((p)[1]<<8) | (p)[0])
-#define GETLONG(p) ((GETSHORT((p)+2) << 16) | GETSHORT((p)))
-
-typedef struct Dosdir Dosdir;
-struct Dosdir
-{
- char name[8];
- char ext[3];
- uchar attr;
- uchar reserved[10];
- uchar time[2];
- uchar date[2];
- uchar start[2];
- uchar length[4];
-};
-
-static char*
-dosparse(char *from, char *to, int len)
-{
- char c;
-
- memset(to, ' ', len);
- if(from == 0)
- return 0;
- while(len-- > 0){
- c = *from++;
- if(c == '.')
- return from;
- if(c == 0)
- break;
- if(c >= 'a' && c <= 'z')
- *to++ = c + 'A' - 'a';
- else
- *to++ = c;
- }
- return 0;
-}
-
-/*
- * return offset of first file block
- *
- * This is a very simplistic dos file system. It only
- * works on floppies, only looks in the root, and only
- * returns a pointer to the first block of a file.
- *
- * This exists for cpu servers that have no hard disk
- * or nvram to store the key on.
- *
- * Please don't make this any smarter: it stays resident
- * and I'ld prefer not to waste the space on something that
- * runs only at boottime -- presotto.
- */
-static long
-finddosfile(int fd, char *file)
-{
- uchar secbuf[512];
- char name[8];
- char ext[3];
- Dosboot *b;
- Dosdir *root, *dp;
- int nroot, sectsize, rootoff, rootsects, n;
-
- /* dos'ize file name */
- file = dosparse(file, name, 8);
- dosparse(file, ext, 3);
-
- /* read boot block, check for sanity */
- b = (Dosboot*)secbuf;
- if(read(fd, secbuf, sizeof(secbuf)) != sizeof(secbuf))
- return -1;
- if(b->magic[0] != 0xEB || b->magic[1] != 0x3C || b->magic[2] != 0x90)
- return -1;
- sectsize = GETSHORT(b->sectsize);
- if(sectsize != 512)
- return -1;
- rootoff = (GETSHORT(b->nresrv) + b->nfats*GETSHORT(b->fatsize)) * sectsize;
- if(seek(fd, rootoff, 0) < 0)
- return -1;
- nroot = GETSHORT(b->rootsize);
- rootsects = (nroot*sizeof(Dosdir)+sectsize-1)/sectsize;
- if(rootsects <= 0 || rootsects > 64)
- return -1;
-
- /*
- * read root. it is contiguous to make stuff like
- * this easier
- */
- root = malloc(rootsects*sectsize);
- if(read(fd, root, rootsects*sectsize) != rootsects*sectsize)
- return -1;
- n = -1;
- for(dp = root; dp < &root[nroot]; dp++)
- if(memcmp(name, dp->name, 8) == 0 && memcmp(ext, dp->ext, 3) == 0){
- n = GETSHORT(dp->start);
- break;
- }
- free(root);
-
- if(n < 0)
- return -1;
-
- /*
- * dp->start is in cluster units, not sectors. The first
- * cluster is cluster 2 which starts immediately after the
- * root directory
- */
- return rootoff + rootsects*sectsize + (n-2)*sectsize*b->clustsize;
-}
-
--- a/libauthsrv/spake2ee.mpc
+++ /dev/null
@@ -1,63 +1,0 @@
-void spake2ee_h2P(mpint *p, mpint *a, mpint *d, mpint *h, mpint *PX, mpint *PY, mpint *PZ, mpint *PT){
- mpint *n = mpnew(0);
- mpassign(mptwo, n);
- for(;;){
- mpint *tmp1 = mpnew(0);
- legendresymbol(n, p, tmp1);
- mpint *tmp2 = mpnew(0);
- mpassign(mpone, tmp2);
- tmp2->sign = -1;
- if(mpcmp(tmp1, tmp2) != 0){
- mpadd(n, mpone, n);
- }else{
- mpfree(tmp2);
- mpfree(tmp1);
- break;
- }
- mpfree(tmp1);
- mpfree(tmp2);
- }
- mpint *tmp3 = mpnew(0);
- mpmod(h, p, tmp3);
- elligator2(p, a, d, n, tmp3, PX, PY, PZ, PT);
- mpfree(tmp3);
- mpfree(n);
- }
-void spake2ee_1(mpint *p, mpint *a, mpint *d, mpint *x, mpint *GX, mpint *GY, mpint *PX, mpint *PY, mpint *PZ, mpint *PT, mpint *y){
- mpint *T = mpnew(0);
- mpint *Z = mpnew(0);
- mpint *Y = mpnew(0);
- mpint *X = mpnew(0);
- mpint *tmp1 = mpnew(0);
- mpmodmul(GX, GY, p, tmp1);
- edwards_scale(p, a, d, x, GX, GY, mpone, tmp1, X, Y, Z, T);
- mpfree(tmp1);
- edwards_add(p, a, d, X, Y, Z, T, PX, PY, PZ, PT, X, Y, Z, T);
- decaf_encode(p, a, d, X, Y, Z, T, y);
- mpfree(T);
- mpfree(Z);
- mpfree(Y);
- mpfree(X);
- }
-void spake2ee_2(mpint *p, mpint *a, mpint *d, mpint *PX, mpint *PY, mpint *PZ, mpint *PT, mpint *x, mpint *y, mpint *ok, mpint *z){
- mpint *T = mpnew(0);
- mpint *Z = mpnew(0);
- mpint *Y = mpnew(0);
- mpint *X = mpnew(0);
- decaf_decode(p, a, d, y, ok, X, Y, Z, T);
- if(mpcmp(ok, mpzero) != 0){
- mpint *tmp1 = mpnew(0);
- mpmodsub(mpzero, PX, p, tmp1);
- mpint *tmp2 = mpnew(0);
- mpmodsub(mpzero, PT, p, tmp2);
- edwards_add(p, a, d, X, Y, Z, T, tmp1, PY, PZ, tmp2, X, Y, Z, T);
- mpfree(tmp1);
- mpfree(tmp2);
- edwards_scale(p, a, d, x, X, Y, Z, T, X, Y, Z, T);
- decaf_encode(p, a, d, X, Y, Z, T, z);
- }
- mpfree(T);
- mpfree(Z);
- mpfree(Y);
- mpfree(X);
- }
--- a/libc/Makefile
+++ b/libc/Makefile
@@ -11,7 +11,6 @@
convM2S.$O\
convS2M.$O\
ctime.$O\
- crypt.$O\
dial.$O\
dirfstat.$O\
dirfwstat.$O\
@@ -41,8 +40,6 @@
netmkaddr.$O\
nsec.$O\
pow10.$O\
- pushssl.$O\
- pushtls.$O\
read9pmsg.$O\
readn.$O\
rune.$O\
--- a/libc/crypt.c
+++ /dev/null
@@ -1,67 +1,0 @@
-/*
- * Data Encryption Standard
- * D.P.Mitchell 83/06/08.
- *
- * block_cipher(key, block, decrypting)
- *
- * these routines use the non-standard 7 byte format
- * for DES keys.
- */
-#include <u.h>
-#include <libc.h>
-#include <libsec.h>
-
-/*
- * destructively encrypt the buffer, which
- * must be at least 8 characters long.
- */
-int
-encrypt(void *key, void *vbuf, int n)
-{
- ulong ekey[32];
- uchar *buf;
- int i, r;
-
- if(n < 8)
- return 0;
- key_setup(key, ekey);
- buf = vbuf;
- n--;
- r = n % 7;
- n /= 7;
- for(i = 0; i < n; i++){
- block_cipher(ekey, buf, 0);
- buf += 7;
- }
- if(r)
- block_cipher(ekey, buf - 7 + r, 0);
- return 1;
-}
-
-/*
- * destructively decrypt the buffer, which
- * must be at least 8 characters long.
- */
-int
-decrypt(void *key, void *vbuf, int n)
-{
- ulong ekey[128];
- uchar *buf;
- int i, r;
-
- if(n < 8)
- return 0;
- key_setup(key, ekey);
- buf = vbuf;
- n--;
- r = n % 7;
- n /= 7;
- buf += n * 7;
- if(r)
- block_cipher(ekey, buf - 7 + r, 1);
- for(i = 0; i < n; i++){
- buf -= 7;
- block_cipher(ekey, buf, 1);
- }
- return 1;
-}
--- a/libc/pushssl.c
+++ /dev/null
@@ -1,44 +1,0 @@
-#include <u.h>
-#include <libc.h>
-
-/*
- * Since the SSL device uses decimal file descriptors to name channels,
- * it is impossible for a user-level file server to stand in for the kernel device.
- * Thus we hard-code #D rather than use /net/ssl.
- */
-
-int
-pushssl(int fd, char *alg, char *secin, char *secout, int *cfd)
-{
- char buf[8];
- char dname[64];
- int n, data, ctl;
-
- ctl = open("#D/ssl/clone", ORDWR);
- if(ctl < 0)
- return -1;
- n = read(ctl, buf, sizeof(buf)-1);
- if(n < 0)
- goto error;
- buf[n] = 0;
- sprint(dname, "#D/ssl/%s/data", buf);
- data = open(dname, ORDWR);
- if(data < 0)
- goto error;
- if(fprint(ctl, "fd %d", fd) < 0 ||
- fprint(ctl, "secretin %s", secin) < 0 ||
- fprint(ctl, "secretout %s", secout) < 0 ||
- fprint(ctl, "alg %s", alg) < 0){
- close(data);
- goto error;
- }
- close(fd);
- if(cfd != 0)
- *cfd = ctl;
- else
- close(ctl);
- return data;
-error:
- close(ctl);
- return -1;
-}
--- a/libc/pushtls.c
+++ /dev/null
@@ -1,99 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <auth.h>
-#include <mp.h>
-#include <libsec.h>
-
-enum {
- TLSFinishedLen = 12,
- HFinished = 20,
-};
-
-static int
-finished(int hand, int isclient)
-{
- int i, n;
- uchar buf[500], buf2[500];
-
- buf[0] = HFinished;
- buf[1] = TLSFinishedLen>>16;
- buf[2] = TLSFinishedLen>>8;
- buf[3] = TLSFinishedLen;
- n = TLSFinishedLen+4;
-
- for(i=0; i<2; i++){
- if(i==0)
- memmove(buf+4, "client finished", TLSFinishedLen);
- else
- memmove(buf+4, "server finished", TLSFinishedLen);
- if(isclient == 1-i){
- if(write(hand, buf, n) != n)
- return -1;
- }else{
- if(readn(hand, buf2, n) != n || memcmp(buf,buf2,n) != 0)
- return -1;
- }
- }
- return 1;
-}
-
-
-// given a plain fd and secrets established beforehand, return encrypted connection
-int
-pushtls(int fd, char *hashalg, char *encalg, int isclient, char *secret, char *dir)
-{
- char buf[8];
- char dname[64];
- int n, data, ctl, hand;
-
- // open a new filter; get ctl fd
- data = hand = -1;
- // /net/tls uses decimal file descriptors to name channels, hence a
- // user-level file server can't stand in for #a; may as well hard-code it.
- ctl = open("#a/tls/clone", ORDWR);
- if(ctl < 0)
- goto error;
- n = read(ctl, buf, sizeof(buf)-1);
- if(n < 0)
- goto error;
- buf[n] = 0;
- if(dir)
- sprint(dir, "#a/tls/%s", buf);
-
- // get application fd
- sprint(dname, "#a/tls/%s/data", buf);
- data = open(dname, ORDWR);
- if(data < 0)
- goto error;
-
- // get handshake fd
- sprint(dname, "#a/tls/%s/hand", buf);
- hand = open(dname, ORDWR);
- if(hand < 0)
- goto error;
-
- // speak a minimal handshake
- if(fprint(ctl, "fd %d 0x301", fd) < 0 ||
- fprint(ctl, "version 0x301") < 0 ||
- fprint(ctl, "secret %s %s %d %s", hashalg, encalg, isclient, secret) < 0 ||
- fprint(ctl, "changecipher") < 0 ||
- finished(hand, isclient) < 0 ||
- fprint(ctl, "opened") < 0){
- close(hand);
- hand = -1;
- goto error;
- }
- close(ctl);
- close(hand);
- close(fd);
- return data;
-
-error:
- if(data>=0)
- close(data);
- if(ctl>=0)
- close(ctl);
- if(hand>=0)
- close(hand);
- return -1;
-}
--- a/libip/Makefile
+++ /dev/null
@@ -1,19 +1,0 @@
-ROOT=..
-include ../Make.config
-LIB=libip.a
-
-OFILES=\
- eipfmt.$O\
- parseip.$O\
- classmask.$O\
- bo.$O\
- ipaux.$O\
-
-default: $(LIB)
-$(LIB): $(OFILES)
- $(AR) r $(LIB) $(OFILES)
- $(RANLIB) $(LIB)
-
-%.$O: %.c
- $(CC) $(CFLAGS) $*.c
-
--- a/libip/bo.c
+++ /dev/null
@@ -1,77 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <ip.h>
-
-void
-hnputv(void *p, uvlong v)
-{
- uchar *a;
-
- a = p;
- a[0] = v>>56;
- a[1] = v>>48;
- a[2] = v>>40;
- a[3] = v>>32;
- a[4] = v>>24;
- a[5] = v>>16;
- a[6] = v>>8;
- a[7] = v;
-}
-
-void
-hnputl(void *p, uint v)
-{
- uchar *a;
-
- a = p;
- a[0] = v>>24;
- a[1] = v>>16;
- a[2] = v>>8;
- a[3] = v;
-}
-
-void
-hnputs(void *p, ushort v)
-{
- uchar *a;
-
- a = p;
- a[0] = v>>8;
- a[1] = v;
-}
-
-uvlong
-nhgetv(void *p)
-{
- uchar *a;
- uvlong v;
-
- a = p;
- v = (uvlong)a[0]<<56;
- v |= (uvlong)a[1]<<48;
- v |= (uvlong)a[2]<<40;
- v |= (uvlong)a[3]<<32;
- v |= a[4]<<24;
- v |= a[5]<<16;
- v |= a[6]<<8;
- v |= a[7]<<0;
- return v;
-}
-
-uint
-nhgetl(void *p)
-{
- uchar *a;
-
- a = p;
- return (a[0]<<24)|(a[1]<<16)|(a[2]<<8)|(a[3]<<0);
-}
-
-ushort
-nhgets(void *p)
-{
- uchar *a;
-
- a = p;
- return (a[0]<<8)|(a[1]<<0);
-}
--- a/libip/classmask.c
+++ /dev/null
@@ -1,86 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <ip.h>
-
-static uchar classmask[4][16] = {
- 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0x00,0x00,0x00,
- 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0x00,0x00,0x00,
- 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x00,0x00,
- 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0x00,
-};
-
-static uchar v6loopback[IPaddrlen] = {
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0x01
-};
-
-static uchar v6linklocal[IPaddrlen] = {
- 0xfe, 0x80, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0
-};
-static uchar v6linklocalmask[IPaddrlen] = {
- 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff,
- 0, 0, 0, 0,
- 0, 0, 0, 0
-};
-static int v6llpreflen = 8; /* link-local prefix length in bytes */
-
-static uchar v6multicast[IPaddrlen] = {
- 0xff, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0
-};
-static uchar v6multicastmask[IPaddrlen] = {
- 0xff, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0
-};
-static int v6mcpreflen = 1; /* multicast prefix length */
-
-static uchar v6solicitednode[IPaddrlen] = {
- 0xff, 0x02, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0x01,
- 0xff, 0, 0, 0
-};
-static uchar v6solicitednodemask[IPaddrlen] = {
- 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff,
- 0xff, 0x0, 0x0, 0x0
-};
-static int v6snpreflen = 13;
-
-uchar*
-defmask(uchar *ip)
-{
- if(isv4(ip))
- return classmask[ip[IPv4off]>>6];
- else {
- if(ipcmp(ip, v6loopback) == 0)
- return IPallbits;
- else if(memcmp(ip, v6linklocal, v6llpreflen) == 0)
- return v6linklocalmask;
- else if(memcmp(ip, v6solicitednode, v6snpreflen) == 0)
- return v6solicitednodemask;
- else if(memcmp(ip, v6multicast, v6mcpreflen) == 0)
- return v6multicastmask;
- return IPallbits;
- }
-}
-
-void
-maskip(uchar *from, uchar *mask, uchar *to)
-{
- int i;
-
- for(i = 0; i < IPaddrlen; i++)
- to[i] = from[i] & mask[i];
-}
--- a/libip/eipfmt.c
+++ /dev/null
@@ -1,109 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <ip.h>
-
-enum
-{
- Isprefix= 16,
-};
-
-uchar prefixvals[256] =
-{
-[0x00] 0 | Isprefix,
-[0x80] 1 | Isprefix,
-[0xC0] 2 | Isprefix,
-[0xE0] 3 | Isprefix,
-[0xF0] 4 | Isprefix,
-[0xF8] 5 | Isprefix,
-[0xFC] 6 | Isprefix,
-[0xFE] 7 | Isprefix,
-[0xFF] 8 | Isprefix,
-};
-
-int
-eipfmt(Fmt *f)
-{
- char buf[5*8];
- static char *efmt = "%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux";
- static char *ifmt = "%d.%d.%d.%d";
- uchar *p, ip[16];
- ulong *lp;
- ushort s;
- int i, j, n, eln, eli;
-
- switch(f->r) {
- case 'E': /* Ethernet address */
- p = va_arg(f->args, uchar*);
- snprint(buf, sizeof buf, efmt, p[0], p[1], p[2], p[3], p[4], p[5]);
- return fmtstrcpy(f, buf);
-
- case 'I': /* Ip address */
- p = va_arg(f->args, uchar*);
-common:
- if(memcmp(p, v4prefix, 12) == 0){
- snprint(buf, sizeof buf, ifmt, p[12], p[13], p[14], p[15]);
- return fmtstrcpy(f, buf);
- }
-
- /* find longest elision */
- eln = eli = -1;
- for(i = 0; i < 16; i += 2){
- for(j = i; j < 16; j += 2)
- if(p[j] != 0 || p[j+1] != 0)
- break;
- if(j > i && j - i > eln){
- eli = i;
- eln = j - i;
- }
- }
-
- /* print with possible elision */
- n = 0;
- for(i = 0; i < 16; i += 2){
- if(i == eli){
- n += sprint(buf+n, "::");
- i += eln;
- if(i >= 16)
- break;
- } else if(i != 0)
- n += sprint(buf+n, ":");
- s = (p[i]<<8) + p[i+1];
- n += sprint(buf+n, "%ux", s);
- }
- return fmtstrcpy(f, buf);
-
- case 'i': /* v6 address as 4 longs */
- lp = va_arg(f->args, ulong*);
- for(i = 0; i < 4; i++)
- hnputl(ip+4*i, *lp++);
- p = ip;
- goto common;
-
- case 'V': /* v4 ip address */
- p = va_arg(f->args, uchar*);
- snprint(buf, sizeof buf, ifmt, p[0], p[1], p[2], p[3]);
- return fmtstrcpy(f, buf);
-
- case 'M': /* ip mask */
- p = va_arg(f->args, uchar*);
-
- /* look for a prefix mask */
- for(i = 0; i < 16; i++)
- if(p[i] != 0xff)
- break;
- if(i < 16){
- if((prefixvals[p[i]] & Isprefix) == 0)
- goto common;
- for(j = i+1; j < 16; j++)
- if(p[j] != 0)
- goto common;
- n = 8*i + (prefixvals[p[i]] & ~Isprefix);
- } else
- n = 8*16;
-
- /* got one, use /xx format */
- snprint(buf, sizeof buf, "/%d", n);
- return fmtstrcpy(f, buf);
- }
- return fmtstrcpy(f, "(eipfmt)");
-}
--- a/libip/ipaux.c
+++ /dev/null
@@ -1,102 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <ip.h>
-
-/*
- * well known IP addresses
- */
-uchar IPv4bcast[IPaddrlen] = {
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff
-};
-uchar IPv4allsys[IPaddrlen] = {
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0xff, 0xff,
- 0xe0, 0, 0, 0x01
-};
-uchar IPv4allrouter[IPaddrlen] = {
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0xff, 0xff,
- 0xe0, 0, 0, 0x02
-};
-uchar IPallbits[IPaddrlen] = {
- 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff
-};
-uchar IPnoaddr[IPaddrlen];
-
-/*
- * prefix of all v4 addresses
- */
-uchar v4prefix[IPaddrlen] = {
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0xff, 0xff,
- 0, 0, 0, 0
-};
-
-int
-isv4(uchar *ip)
-{
- return memcmp(ip, v4prefix, IPv4off) == 0;
-}
-
-/*
- * the following routines are unrolled with no memset's to speed
- * up the usual case
- */
-void
-v4tov6(uchar *v6, uchar *v4)
-{
- v6[0] = 0;
- v6[1] = 0;
- v6[2] = 0;
- v6[3] = 0;
- v6[4] = 0;
- v6[5] = 0;
- v6[6] = 0;
- v6[7] = 0;
- v6[8] = 0;
- v6[9] = 0;
- v6[10] = 0xff;
- v6[11] = 0xff;
- v6[12] = v4[0];
- v6[13] = v4[1];
- v6[14] = v4[2];
- v6[15] = v4[3];
-}
-
-int
-v6tov4(uchar *v4, uchar *v6)
-{
- if(v6[0] == 0
- && v6[1] == 0
- && v6[2] == 0
- && v6[3] == 0
- && v6[4] == 0
- && v6[5] == 0
- && v6[6] == 0
- && v6[7] == 0
- && v6[8] == 0
- && v6[9] == 0
- && v6[10] == 0xff
- && v6[11] == 0xff)
- {
- v4[0] = v6[12];
- v4[1] = v6[13];
- v4[2] = v6[14];
- v4[3] = v6[15];
- return 0;
- } else {
- memset(v4, 0, 4);
- if(memcmp(v6, IPnoaddr, IPaddrlen) == 0)
- return 0;
- return -1;
- }
-}
--- a/libip/parseip.c
+++ /dev/null
@@ -1,176 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <ctype.h>
-#include <ip.h>
-
-char*
-v4parseip(uchar *to, char *from)
-{
- int i;
- char *p;
-
- p = from;
- for(i = 0; i < 4 && *p; i++){
- to[i] = strtoul(p, &p, 0);
- if(*p == '.')
- p++;
- }
- switch(CLASS(to)){
- case 0: /* class A - 1 uchar net */
- case 1:
- if(i == 3){
- to[3] = to[2];
- to[2] = to[1];
- to[1] = 0;
- } else if (i == 2){
- to[3] = to[1];
- to[1] = 0;
- }
- break;
- case 2: /* class B - 2 uchar net */
- if(i == 3){
- to[3] = to[2];
- to[2] = 0;
- }
- break;
- }
- return p;
-}
-
-static int
-ipcharok(int c)
-{
- return c == '.' || c == ':' || (isascii(c) && isxdigit(c));
-}
-
-static int
-delimchar(int c)
-{
- if(c == '\0')
- return 1;
- if(c == '.' || c == ':' || (isascii(c) && isalnum(c)))
- return 0;
- return 1;
-}
-
-/*
- * `from' may contain an address followed by other characters,
- * at least in /boot, so we permit whitespace (and more) after the address.
- * we do ensure that "delete" cannot be parsed as "de::".
- *
- * some callers don't check the return value for errors, so
- * set `to' to something distinctive in the case of a parse error.
- */
-vlong
-parseip(uchar *to, char *from)
-{
- int i, elipsis = 0, v4 = 1;
- ulong x;
- char *p, *op;
-
- memset(to, 0, IPaddrlen);
- p = from;
- for(i = 0; i < IPaddrlen && ipcharok(*p); i+=2){
- op = p;
- x = strtoul(p, &p, 16);
- if(*p == '.' || (*p == 0 && i == 0)){ /* ends with v4? */
- if(i > IPaddrlen-4){
- memset(to, 0, IPaddrlen);
- return -1; /* parse error */
- }
- p = v4parseip(to+i, op);
- i += 4;
- break;
- }
- /* v6: at most 4 hex digits, followed by colon or delim */
- if(x != (ushort)x || (*p != ':' && !delimchar(*p))) {
- memset(to, 0, IPaddrlen);
- return -1; /* parse error */
- }
- to[i] = x>>8;
- to[i+1] = x;
- if(*p == ':'){
- v4 = 0;
- if(*++p == ':'){ /* :: is elided zero short(s) */
- if (elipsis) {
- memset(to, 0, IPaddrlen);
- return -1; /* second :: */
- }
- elipsis = i+2;
- p++;
- }
- } else if (p == op) /* strtoul made no progress? */
- break;
- }
- if (p == from || !delimchar(*p)) {
- memset(to, 0, IPaddrlen);
- return -1; /* parse error */
- }
- if(i < IPaddrlen){
- memmove(&to[elipsis+IPaddrlen-i], &to[elipsis], i-elipsis);
- memset(&to[elipsis], 0, IPaddrlen-i);
- }
- if(v4){
- to[10] = to[11] = 0xff;
- return (ulong)nhgetl(to + IPv4off);
- } else
- return 6;
-}
-
-/*
- * hack to allow ip v4 masks to be entered in the old
- * style
- */
-vlong
-parseipmask(uchar *to, char *from, int v4)
-{
- vlong x;
- int i, w;
- uchar *p;
-
- if(*from == '/'){
- /* as a number of prefix bits */
- i = atoi(from+1);
- if(i < 0)
- i = 0;
- if(i <= 32 && v4)
- i += 96;
- if(i > 128)
- i = 128;
- w = i;
- memset(to, 0, IPaddrlen);
- for(p = to; i >= 8; i -= 8)
- *p++ = 0xff;
- if(i > 0)
- *p = ~((1<<(8-i))-1);
- /*
- * identify as ipv6 if the mask is inexpressible as a v4 mask
- * (because it has too few mask bits). Arguably, we could
- * always return 6 here.
- */
- if (w < 96)
- return v4 ? -1 : 6;
- x = (ulong)nhgetl(to+IPv4off);
- } else {
- /* as a straight v4 bit mask */
- x = parseip(to, from);
- if(memcmp(to, v4prefix, IPv4off) == 0)
- memset(to, 0xff, IPv4off);
- else if(v4 && memcmp(to, IPallbits, IPv4off) != 0)
- x = -1;
- }
- return x;
-}
-
-vlong
-parseipandmask(uchar *ip, uchar *mask, char *ipstr, char *maskstr)
-{
- vlong x;
-
- x = parseip(ip, ipstr);
- if(maskstr == nil)
- memset(mask, 0xff, IPaddrlen);
- else if(parseipmask(mask, maskstr, memcmp(ip, v4prefix, IPv4off) == 0) == -1)
- x = -1;
- return x;
-}
--- a/libmp/Makefile
+++ /dev/null
@@ -1,56 +1,0 @@
-ROOT=..
-include ../Make.config
-# N.B. This is used only for secstore. It needn't be fast.
-
-LIB=libmp.a
-
-OFILES=\
- betomp.$O\
- cnfield.$O\
- crt.$O\
- gmfield.$O\
- letomp.$O\
- mpadd.$O\
- mpaux.$O\
- mpcmp.$O\
- mpdigdiv.$O\
- mpdiv.$O\
- mpexp.$O\
- mpextendedgcd.$O\
- mpfactorial.$O\
- mpfield.$O\
- mpfmt.$O\
- mpinvert.$O\
- mpleft.$O\
- mplogic.$O\
- mpmod.$O\
- mpmodop.$O\
- mpmul.$O\
- mpnrand.$O\
- mprand.$O\
- mpright.$O\
- mpsel.$O\
- mpsub.$O\
- mptobe.$O\
- mptober.$O\
- mptoi.$O\
- mptole.$O\
- mptolel.$O\
- mptoui.$O\
- mptouv.$O\
- mptov.$O\
- mpvecadd.$O\
- mpveccmp.$O\
- mpvecdigmuladd.$O\
- mpvecsub.$O\
- mpvectscmp.$O\
- strtomp.$O
-
-default: $(LIB)
-$(LIB): $(OFILES)
- $(AR) r $(LIB) $(OFILES)
- $(RANLIB) $(LIB)
-
-%.$O: %.c
- $(CC) $(CFLAGS) $*.c
-
--- a/libmp/betomp.c
+++ /dev/null
@@ -1,34 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-// convert a big-endian byte array (most significant byte first) to an mpint
-mpint*
-betomp(uchar *p, uint n, mpint *b)
-{
- int m, s;
- mpdigit x;
-
- if(b == nil){
- b = mpnew(0);
- setmalloctag(b, getcallerpc(&p));
- }
- mpbits(b, n*8);
-
- m = DIGITS(n*8);
- b->top = m--;
- b->sign = 1;
-
- s = ((n-1)*8)%Dbits;
- x = 0;
- for(; n > 0; n--){
- x |= ((mpdigit)(*p++)) << s;
- s -= 8;
- if(s < 0){
- b->p[m--] = x;
- s = Dbits-8;
- x = 0;
- }
- }
- return mpnorm(b);
-}
--- a/libmp/cnfield.c
+++ /dev/null
@@ -1,114 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-/*
- * fast reduction for crandall numbers of the form: 2^n - c
- */
-
-enum {
- MAXDIG = 1024 / Dbits,
-};
-
-typedef struct CNfield CNfield;
-struct CNfield
-{
- Mfield f;
-
- mpint m[1];
-
- int s;
- mpdigit c;
-};
-
-static int
-cnreduce(Mfield *m, mpint *a, mpint *r)
-{
- mpdigit q[MAXDIG-1], t[MAXDIG], d;
- CNfield *f = (CNfield*)m;
- int qn, tn, k;
-
- k = f->f.m.top;
- if((a->top - k) >= MAXDIG)
- return -1;
-
- mpleft(a, f->s, r);
- if(r->top <= k)
- mpbits(r, (k+1)*Dbits);
-
- /* q = hi(r) */
- qn = r->top - k;
- memmove(q, r->p+k, qn*Dbytes);
-
- /* r = lo(r) */
- r->top = k;
- r->sign = 1;
-
- do {
- /* t = q*c */
- tn = qn+1;
- memset(t, 0, tn*Dbytes);
- mpvecdigmuladd(q, qn, f->c, t);
-
- /* q = hi(t) */
- qn = tn - k;
- if(qn <= 0) qn = 0;
- else memmove(q, t+k, qn*Dbytes);
-
- /* r += lo(t) */
- if(tn > k)
- tn = k;
- mpvecadd(r->p, k, t, tn, r->p);
-
- /* if(r >= m) r -= m */
- mpvecsub(r->p, k+1, f->m->p, k, t);
- d = t[k];
- for(tn = 0; tn < k; tn++)
- r->p[tn] = (r->p[tn] & d) | (t[tn] & ~d);
- } while(qn > 0);
-
- if(f->s != 0)
- mpright(r, f->s, r);
- mpnorm(r);
-
- return 0;
-}
-
-Mfield*
-cnfield(mpint *N)
-{
- mpint *M, *C;
- CNfield *f;
- mpdigit d;
- int s;
-
- if(N->top <= 2 || N->top >= MAXDIG)
- return nil;
- f = nil;
- d = N->p[N->top-1];
- for(s = 0; (d & (mpdigit)1<<(Dbits-1)) == 0; s++)
- d <<= 1;
- C = mpnew(0);
- M = mpcopy(N);
- mpleft(N, s, M);
- mpleft(mpone, M->top*Dbits, C);
- mpsub(C, M, C);
- if(C->top != 1)
- goto out;
- f = mallocz(sizeof(CNfield) + M->top*sizeof(mpdigit), 1);
- if(f == nil)
- goto out;
- f->s = s;
- f->c = C->p[0];
- f->m->size = M->top;
- f->m->p = (mpdigit*)&f[1];
- mpassign(M, f->m);
- mpassign(N, (mpint*)f);
- f->f.reduce = cnreduce;
- f->f.m.flags |= MPfield;
-out:
- mpfree(M);
- mpfree(C);
-
- return (Mfield*)f;
-}
--- a/libmp/crt.c
+++ /dev/null
@@ -1,121 +1,0 @@
-#include "os.h"
-#include <mp.h>
-
-// chinese remainder theorem
-//
-// handbook of applied cryptography, menezes et al, 1997, pp 610 - 613
-
-struct CRTpre
-{
- int n; // number of moduli
- mpint **m; // pointer to moduli
- mpint **c; // precomputed coefficients
- mpint **p; // precomputed products
- mpint *a[1]; // local storage
-};
-
-// setup crt info, returns a newly created structure
-CRTpre*
-crtpre(int n, mpint **m)
-{
- CRTpre *crt;
- int i, j;
- mpint *u;
-
- crt = malloc(sizeof(CRTpre)+sizeof(mpint)*3*n);
- if(crt == nil)
- sysfatal("crtpre: %r");
- crt->m = crt->a;
- crt->c = crt->a+n;
- crt->p = crt->c+n;
- crt->n = n;
-
- // make a copy of the moduli
- for(i = 0; i < n; i++)
- crt->m[i] = mpcopy(m[i]);
-
- // precompute the products
- u = mpcopy(mpone);
- for(i = 0; i < n; i++){
- mpmul(u, m[i], u);
- crt->p[i] = mpcopy(u);
- }
-
- // precompute the coefficients
- for(i = 1; i < n; i++){
- crt->c[i] = mpcopy(mpone);
- for(j = 0; j < i; j++){
- mpinvert(m[j], m[i], u);
- mpmul(u, crt->c[i], u);
- mpmod(u, m[i], crt->c[i]);
- }
- }
-
- mpfree(u);
-
- return crt;
-}
-
-void
-crtprefree(CRTpre *crt)
-{
- int i;
-
- for(i = 0; i < crt->n; i++){
- if(i != 0)
- mpfree(crt->c[i]);
- mpfree(crt->p[i]);
- mpfree(crt->m[i]);
- }
- free(crt);
-}
-
-// convert to residues, returns a newly created structure
-CRTres*
-crtin(CRTpre *crt, mpint *x)
-{
- int i;
- CRTres *res;
-
- res = malloc(sizeof(CRTres)+sizeof(mpint)*crt->n);
- if(res == nil)
- sysfatal("crtin: %r");
- res->n = crt->n;
- for(i = 0; i < res->n; i++){
- res->r[i] = mpnew(0);
- mpmod(x, crt->m[i], res->r[i]);
- }
- return res;
-}
-
-// garners algorithm for converting residue form to linear
-void
-crtout(CRTpre *crt, CRTres *res, mpint *x)
-{
- mpint *u;
- int i;
-
- u = mpnew(0);
- mpassign(res->r[0], x);
-
- for(i = 1; i < crt->n; i++){
- mpsub(res->r[i], x, u);
- mpmul(u, crt->c[i], u);
- mpmod(u, crt->m[i], u);
- mpmul(u, crt->p[i-1], u);
- mpadd(x, u, x);
- }
-
- mpfree(u);
-}
-
-// free the residue
-void
-crtresfree(CRTres *res)
-{
- int i;
-
- for(i = 0; i < res->n; i++)
- mpfree(res->r[i]);
- free(res);
-}
--- a/libmp/crttest.c
+++ /dev/null
@@ -1,52 +1,0 @@
-#include "os.h"
-#include <mp.h>
-
-void
-testcrt(mpint **p)
-{
- CRTpre *crt;
- CRTres *res;
- mpint *m, *x, *y;
-
- fmtinstall('B', mpfmt);
-
- // get a modulus and a test number
- m = mpnew(1024+160);
- mpmul(p[0], p[1], m);
- x = mpnew(1024+160);
- mpadd(m, mpone, x);
-
- // do the precomputation for crt conversion
- crt = crtpre(2, p);
-
- // convert x to residues
- res = crtin(crt, x);
-
- // convert back
- y = mpnew(1024+160);
- crtout(crt, res, y);
- print("x %B\ny %B\n", x, y);
- mpfree(m);
- mpfree(x);
- mpfree(y);
-}
-
-void
-main(void)
-{
- int i;
- mpint *p[2];
- long start;
-
- start = time(0);
- for(i = 0; i < 10; i++){
- p[0] = mpnew(1024);
- p[1] = mpnew(1024);
- DSAprimes(p[0], p[1], nil);
- testcrt(p);
- mpfree(p[0]);
- mpfree(p[1]);
- }
- print("%ld secs with more\n", time(0)-start);
- exits(0);
-}
--- a/libmp/dat.h
+++ /dev/null
@@ -1,12 +1,0 @@
-#define mpdighi (mpdigit)(1<<(Dbits-1))
-#define DIGITS(x) ((Dbits - 1 + (x))/Dbits)
-
-// for converting between int's and mpint's
-#define MAXUINT ((uint)-1)
-#define MAXINT (MAXUINT>>1)
-#define MININT (MAXINT+1)
-
-// for converting between vlongs's and mpint's
-#define MAXUVLONG (~0ULL)
-#define MAXVLONG (MAXUVLONG>>1)
-#define MINVLONG (MAXVLONG+1ULL)
--- a/libmp/gmfield.c
+++ /dev/null
@@ -1,173 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-/*
- * fast reduction for generalized mersenne numbers (GM)
- * using a series of additions and subtractions.
- */
-
-enum {
- MAXDIG = 1024/Dbits,
-};
-
-typedef struct GMfield GMfield;
-struct GMfield
-{
- Mfield f;
-
- mpint m2[1];
-
- int nadd;
- int nsub;
- int indx[256];
-};
-
-static int
-gmreduce(Mfield *m, mpint *a, mpint *r)
-{
- GMfield *g = (GMfield*)m;
- mpdigit d0, t[MAXDIG];
- int i, j, d, *x;
-
- if(mpmagcmp(a, g->m2) >= 0)
- return -1;
-
- if(a != r)
- mpassign(a, r);
-
- d = g->f.m.top;
- mpbits(r, (d+1)*Dbits*2);
- memmove(t+d, r->p+d, d*Dbytes);
-
- r->sign = 1;
- r->top = d;
- r->p[d] = 0;
-
- if(g->nsub > 0)
- mpvecdigmuladd(g->f.m.p, d, g->nsub, r->p);
-
- x = g->indx;
- for(i=0; i<g->nadd; i++){
- t[0] = 0;
- d0 = t[*x++];
- for(j=1; j<d; j++)
- t[j] = t[*x++];
- t[0] = d0;
-
- mpvecadd(r->p, d+1, t, d, r->p);
- }
-
- for(i=0; i<g->nsub; i++){
- t[0] = 0;
- d0 = t[*x++];
- for(j=1; j<d; j++)
- t[j] = t[*x++];
- t[0] = d0;
-
- mpvecsub(r->p, d+1, t, d, r->p);
- }
-
- mpvecdigmulsub(g->f.m.p, d, r->p[d], r->p);
- r->p[d] = 0;
-
- mpvecsub(r->p, d+1, g->f.m.p, d, r->p+d+1);
- d0 = r->p[2*d+1];
- for(j=0; j<d; j++)
- r->p[j] = (r->p[j] & d0) | (r->p[j+d+1] & ~d0);
-
- mpnorm(r);
-
- return 0;
-}
-
-Mfield*
-gmfield(mpint *N)
-{
- int i,j,d, s, *C, *X, *x, *e;
- mpint *M, *T;
- GMfield *g;
-
- d = N->top;
- if(d <= 2 || d > MAXDIG/2 || (mpsignif(N) % Dbits) != 0)
- return nil;
- g = nil;
- T = mpnew(0);
- M = mpcopy(N);
- C = malloc(sizeof(int)*(d+1));
- X = malloc(sizeof(int)*(d*d));
- if(C == nil || X == nil)
- goto out;
-
- for(i=0; i<=d; i++){
- if((M->p[i]>>8) != 0 && (~M->p[i]>>8) != 0)
- goto out;
- j = M->p[i];
- C[d - i] = -j;
- itomp(j, T);
- mpleft(T, i*Dbits, T);
- mpsub(M, T, M);
- }
- for(j=0; j<d; j++)
- X[j] = C[d-j];
- for(i=1; i<d; i++){
- X[d*i] = X[d*(i-1) + d-1]*C[d];
- for(j=1; j<d; j++)
- X[d*i + j] = X[d*(i-1) + j-1] + X[d*(i-1) + d-1]*C[d-j];
- }
- g = mallocz(sizeof(GMfield) + (d+1)*sizeof(mpdigit)*2, 1);
- if(g == nil)
- goto out;
-
- g->m2->p = (mpdigit*)&g[1];
- g->m2->size = d*2+1;
- mpmul(N, N, g->m2);
- mpassign(N, (mpint*)g);
- g->f.reduce = gmreduce;
- g->f.m.flags |= MPfield;
-
- s = 0;
- x = g->indx;
- e = x + nelem(g->indx) - d;
- for(g->nadd=0; x <= e; x += d, g->nadd++){
- s = 0;
- for(i=0; i<d; i++){
- for(j=0; j<d; j++){
- if(X[d*i+j] > 0 && x[j] == 0){
- X[d*i+j]--;
- x[j] = d+i;
- s = 1;
- break;
- }
- }
- }
- if(s == 0)
- break;
- }
- for(g->nsub=0; x <= e; x += d, g->nsub++){
- s = 0;
- for(i=0; i<d; i++){
- for(j=0; j<d; j++){
- if(X[d*i+j] < 0 && x[j] == 0){
- X[d*i+j]++;
- x[j] = d+i;
- s = 1;
- break;
- }
- }
- }
- if(s == 0)
- break;
- }
- if(s != 0){
- mpfree((mpint*)g);
- g = nil;
- }
-out:
- free(C);
- free(X);
- mpfree(M);
- mpfree(T);
- return (Mfield*)g;
-}
-
--- a/libmp/letomp.c
+++ /dev/null
@@ -1,31 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-// convert a little endian byte array (least significant byte first) to an mpint
-mpint*
-letomp(uchar *s, uint n, mpint *b)
-{
- int i=0, m = 0;
- mpdigit x=0;
-
- if(b == nil){
- b = mpnew(0);
- setmalloctag(b, getcallerpc(&s));
- }
- mpbits(b, 8*n);
- for(; n > 0; n--){
- x |= ((mpdigit)(*s++)) << i;
- i += 8;
- if(i == Dbits){
- b->p[m++] = x;
- i = 0;
- x = 0;
- }
- }
- if(i > 0)
- b->p[m++] = x;
- b->top = m;
- b->sign = 1;
- return mpnorm(b);
-}
--- a/libmp/mpadd.c
+++ /dev/null
@@ -1,58 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-// sum = abs(b1) + abs(b2), i.e., add the magnitudes
-void
-mpmagadd(mpint *b1, mpint *b2, mpint *sum)
-{
- int m, n;
- mpint *t;
-
- sum->flags |= (b1->flags | b2->flags) & MPtimesafe;
-
- // get the sizes right
- if(b2->top > b1->top){
- t = b1;
- b1 = b2;
- b2 = t;
- }
- n = b1->top;
- m = b2->top;
- if(n == 0){
- mpassign(mpzero, sum);
- return;
- }
- if(m == 0){
- mpassign(b1, sum);
- sum->sign = 1;
- return;
- }
- mpbits(sum, (n+1)*Dbits);
- sum->top = n+1;
-
- mpvecadd(b1->p, n, b2->p, m, sum->p);
- sum->sign = 1;
-
- mpnorm(sum);
-}
-
-// sum = b1 + b2
-void
-mpadd(mpint *b1, mpint *b2, mpint *sum)
-{
- int sign;
-
- if(b1->sign != b2->sign){
- assert(((b1->flags | b2->flags | sum->flags) & MPtimesafe) == 0);
- if(b1->sign < 0)
- mpmagsub(b2, b1, sum);
- else
- mpmagsub(b1, b2, sum);
- } else {
- sign = b1->sign;
- mpmagadd(b1, b2, sum);
- if(sum->top != 0)
- sum->sign = sign;
- }
-}
--- a/libmp/mpaux.c
+++ /dev/null
@@ -1,205 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-static mpdigit _mptwodata[1] = { 2 };
-static mpint _mptwo =
-{
- 1, 1, 1,
- _mptwodata,
- MPstatic|MPnorm
-};
-mpint *mptwo = &_mptwo;
-
-static mpdigit _mponedata[1] = { 1 };
-static mpint _mpone =
-{
- 1, 1, 1,
- _mponedata,
- MPstatic|MPnorm
-};
-mpint *mpone = &_mpone;
-
-static mpdigit _mpzerodata[1] = { 0 };
-static mpint _mpzero =
-{
- 1, 1, 0,
- _mpzerodata,
- MPstatic|MPnorm
-};
-mpint *mpzero = &_mpzero;
-
-static int mpmindigits = 33;
-
-// set minimum digit allocation
-void
-mpsetminbits(int n)
-{
- if(n < 0)
- sysfatal("mpsetminbits: n < 0");
- if(n == 0)
- n = 1;
- mpmindigits = DIGITS(n);
-}
-
-// allocate an n bit 0'd number
-mpint*
-mpnew(int n)
-{
- mpint *b;
-
- if(n < 0)
- sysfatal("mpsetminbits: n < 0");
-
- n = DIGITS(n);
- if(n < mpmindigits)
- n = mpmindigits;
- b = mallocz(sizeof(mpint) + n*Dbytes, 1);
- if(b == nil)
- sysfatal("mpnew: %r");
- setmalloctag(b, getcallerpc(&n));
- b->p = (mpdigit*)&b[1];
- b->size = n;
- b->sign = 1;
- b->flags = MPnorm;
-
- return b;
-}
-
-// guarantee at least n significant bits
-void
-mpbits(mpint *b, int m)
-{
- int n;
-
- n = DIGITS(m);
- if(b->size >= n){
- if(b->top >= n)
- return;
- } else {
- if(b->p == (mpdigit*)&b[1]){
- b->p = (mpdigit*)mallocz(n*Dbytes, 0);
- if(b->p == nil)
- sysfatal("mpbits: %r");
- memmove(b->p, &b[1], Dbytes*b->top);
- memset(&b[1], 0, Dbytes*b->size);
- } else {
- b->p = (mpdigit*)realloc(b->p, n*Dbytes);
- if(b->p == nil)
- sysfatal("mpbits: %r");
- }
- b->size = n;
- }
- memset(&b->p[b->top], 0, Dbytes*(n - b->top));
- b->top = n;
- b->flags &= ~MPnorm;
-}
-
-void
-mpfree(mpint *b)
-{
- if(b == nil)
- return;
- if(b->flags & MPstatic)
- sysfatal("freeing mp constant");
- memset(b->p, 0, b->size*Dbytes);
- if(b->p != (mpdigit*)&b[1])
- free(b->p);
- free(b);
-}
-
-mpint*
-mpnorm(mpint *b)
-{
- int i;
-
- if(b->flags & MPtimesafe){
- assert(b->sign == 1);
- b->flags &= ~MPnorm;
- return b;
- }
- for(i = b->top-1; i >= 0; i--)
- if(b->p[i] != 0)
- break;
- b->top = i+1;
- if(b->top == 0)
- b->sign = 1;
- b->flags |= MPnorm;
- return b;
-}
-
-mpint*
-mpcopy(mpint *old)
-{
- mpint *new;
-
- new = mpnew(Dbits*old->size);
- setmalloctag(new, getcallerpc(&old));
- new->sign = old->sign;
- new->top = old->top;
- new->flags = old->flags & ~(MPstatic|MPfield);
- memmove(new->p, old->p, Dbytes*old->top);
- return new;
-}
-
-void
-mpassign(mpint *old, mpint *new)
-{
- if(new == nil || old == new)
- return;
- new->top = 0;
- mpbits(new, Dbits*old->top);
- new->sign = old->sign;
- new->top = old->top;
- new->flags &= ~MPnorm;
- new->flags |= old->flags & ~(MPstatic|MPfield);
- memmove(new->p, old->p, Dbytes*old->top);
-}
-
-// number of significant bits in mantissa
-int
-mpsignif(mpint *n)
-{
- int i, j;
- mpdigit d;
-
- if(n->top == 0)
- return 0;
- for(i = n->top-1; i >= 0; i--){
- d = n->p[i];
- for(j = Dbits-1; j >= 0; j--){
- if(d & (((mpdigit)1)<<j))
- return i*Dbits + j + 1;
- }
- }
- return 0;
-}
-
-// k, where n = 2**k * q for odd q
-int
-mplowbits0(mpint *n)
-{
- int k, bit, digit;
- mpdigit d;
-
- assert(n->flags & MPnorm);
- if(n->top==0)
- return 0;
- k = 0;
- bit = 0;
- digit = 0;
- d = n->p[0];
- for(;;){
- if(d & (1<<bit))
- break;
- k++;
- bit++;
- if(bit==Dbits){
- if(++digit >= n->top)
- return 0;
- d = n->p[digit];
- bit = 0;
- }
- }
- return k;
-}
--- a/libmp/mpcmp.c
+++ /dev/null
@@ -1,30 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-// return neg, 0, pos as abs(b1)-abs(b2) is neg, 0, pos
-int
-mpmagcmp(mpint *b1, mpint *b2)
-{
- int i;
-
- i = b1->flags | b2->flags;
- if(i & MPtimesafe)
- return mpvectscmp(b1->p, b1->top, b2->p, b2->top);
- if(i & MPnorm){
- i = b1->top - b2->top;
- if(i)
- return i;
- }
- return mpveccmp(b1->p, b1->top, b2->p, b2->top);
-}
-
-// return neg, 0, pos as b1-b2 is neg, 0, pos
-int
-mpcmp(mpint *b1, mpint *b2)
-{
- int sign;
-
- sign = (b1->sign - b2->sign) >> 1; // -1, 0, 1
- return sign | (((sign&1)-1) & mpmagcmp(b1, b2)*b1->sign);
-}
--- a/libmp/mpdigdiv.c
+++ /dev/null
@@ -1,56 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-//
-// divide two digits by one and return quotient
-//
-void
-mpdigdiv(mpdigit *dividend, mpdigit divisor, mpdigit *quotient)
-{
- mpdigit hi, lo, q, x, y;
- int i;
-
- hi = dividend[1];
- lo = dividend[0];
-
- // return highest digit value if the result >= 2**32
- if(hi >= divisor || divisor == 0){
- divisor = 0;
- *quotient = ~divisor;
- return;
- }
-
- // very common case
- if(~divisor == 0){
- lo += hi;
- if(lo < hi){
- hi++;
- lo++;
- }
- if(lo+1 == 0)
- hi++;
- *quotient = hi;
- return;
- }
-
- // at this point we know that hi < divisor
- // just shift and subtract till we're done
- q = 0;
- x = divisor;
- for(i = Dbits-1; hi > 0 && i >= 0; i--){
- x >>= 1;
- if(x > hi)
- continue;
- y = divisor<<i;
- if(x == hi && y > lo)
- continue;
- if(y > lo)
- hi--;
- lo -= y;
- hi -= x;
- q |= 1<<i;
- }
- q += lo/divisor;
- *quotient = q;
-}
--- a/libmp/mpdiv.c
+++ /dev/null
@@ -1,142 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-// division ala knuth, seminumerical algorithms, pp 237-238
-// the numbers are stored backwards to what knuth expects so j
-// counts down rather than up.
-
-void
-mpdiv(mpint *dividend, mpint *divisor, mpint *quotient, mpint *remainder)
-{
- int j, s, vn, sign, qsign, rsign;
- mpdigit qd, *up, *vp, *qp;
- mpint *u, *v, *t;
-
- assert(quotient != remainder);
- assert(divisor->flags & MPnorm);
-
- // divide bv zero
- if(divisor->top == 0)
- abort();
-
- // division by one or small powers of two
- if(divisor->top == 1 && (divisor->p[0] & (divisor->p[0]-1)) == 0){
- vlong r = 0;
- if(dividend->top > 0)
- r = (vlong)dividend->sign * (dividend->p[0] & (divisor->p[0]-1));
- if(quotient != nil){
- sign = divisor->sign;
- for(s = 0; ((divisor->p[0] >> s) & 1) == 0; s++)
- ;
- mpright(dividend, s, quotient);
- if(sign < 0)
- quotient->sign ^= (-mpmagcmp(quotient, mpzero) >> 31) << 1;
- }
- if(remainder != nil){
- remainder->flags |= dividend->flags & MPtimesafe;
- vtomp(r, remainder);
- }
- return;
- }
- assert((dividend->flags & MPtimesafe) == 0);
-
- // quick check
- if(mpmagcmp(dividend, divisor) < 0){
- if(remainder != nil)
- mpassign(dividend, remainder);
- if(quotient != nil)
- mpassign(mpzero, quotient);
- return;
- }
-
- qsign = divisor->sign * dividend->sign;
- rsign = dividend->sign;
-
- // D1: shift until divisor, v, has hi bit set (needed to make trial
- // divisor accurate)
- qd = divisor->p[divisor->top-1];
- for(s = 0; (qd & mpdighi) == 0; s++)
- qd <<= 1;
- u = mpnew((dividend->top+2)*Dbits + s);
- if(s == 0 && divisor != quotient && divisor != remainder) {
- mpassign(dividend, u);
- v = divisor;
- } else {
- mpleft(dividend, s, u);
- v = mpnew(divisor->top*Dbits);
- mpleft(divisor, s, v);
- }
- up = u->p+u->top-1;
- vp = v->p+v->top-1;
- vn = v->top;
-
- // D1a: make sure high digit of dividend is less than high digit of divisor
- if(*up >= *vp){
- *++up = 0;
- u->top++;
- }
-
- // storage for multiplies
- t = mpnew(4*Dbits);
-
- qp = nil;
- if(quotient != nil){
- mpbits(quotient, (u->top - v->top)*Dbits);
- quotient->top = u->top - v->top;
- qp = quotient->p+quotient->top-1;
- }
-
- // D2, D7: loop on length of dividend
- for(j = u->top; j > vn; j--){
-
- // D3: calculate trial divisor
- mpdigdiv(up-1, *vp, &qd);
-
- // D3a: rule out trial divisors 2 greater than real divisor
- if(vn > 1) for(;;){
- memset(t->p, 0, 3*Dbytes); // mpvecdigmuladd adds to what's there
- mpvecdigmuladd(vp-1, 2, qd, t->p);
- if(mpveccmp(t->p, 3, up-2, 3) > 0)
- qd--;
- else
- break;
- }
-
- // D4: u -= v*qd << j*Dbits
- sign = mpvecdigmulsub(v->p, vn, qd, up-vn);
- if(sign < 0){
-
- // D6: trial divisor was too high, add back borrowed
- // value and decrease divisor
- mpvecadd(up-vn, vn+1, v->p, vn, up-vn);
- qd--;
- }
-
- // D5: save quotient digit
- if(qp != nil)
- *qp-- = qd;
-
- // push top of u down one
- u->top--;
- *up-- = 0;
- }
- if(qp != nil){
- assert((quotient->flags & MPtimesafe) == 0);
- mpnorm(quotient);
- if(quotient->top != 0)
- quotient->sign = qsign;
- }
-
- if(remainder != nil){
- assert((remainder->flags & MPtimesafe) == 0);
- mpright(u, s, remainder); // u is the remainder shifted
- if(remainder->top != 0)
- remainder->sign = rsign;
- }
-
- mpfree(t);
- mpfree(u);
- if(v != divisor)
- mpfree(v);
-}
--- a/libmp/mpexp.c
+++ /dev/null
@@ -1,96 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-// res = b**e
-//
-// knuth, vol 2, pp 398-400
-
-enum {
- Freeb= 0x1,
- Freee= 0x2,
- Freem= 0x4,
-};
-
-//int expdebug;
-
-void
-mpexp(mpint *b, mpint *e, mpint *m, mpint *res)
-{
- mpint *t[2];
- int tofree;
- mpdigit d, bit;
- int i, j;
-
- assert(m == nil || m->flags & MPnorm);
- assert((e->flags & MPtimesafe) == 0);
- res->flags |= b->flags & MPtimesafe;
-
- i = mpcmp(e,mpzero);
- if(i==0){
- mpassign(mpone, res);
- return;
- }
- if(i<0)
- sysfatal("mpexp: negative exponent");
-
- t[0] = mpcopy(b);
- t[1] = res;
-
- tofree = 0;
- if(res == b){
- b = mpcopy(b);
- tofree |= Freeb;
- }
- if(res == e){
- e = mpcopy(e);
- tofree |= Freee;
- }
- if(res == m){
- m = mpcopy(m);
- tofree |= Freem;
- }
-
- // skip first bit
- i = e->top-1;
- d = e->p[i];
- for(bit = mpdighi; (bit & d) == 0; bit >>= 1)
- ;
- bit >>= 1;
-
- j = 0;
- for(;;){
- for(; bit != 0; bit >>= 1){
- if(m != nil)
- mpmodmul(t[j], t[j], m, t[j^1]);
- else
- mpmul(t[j], t[j], t[j^1]);
- if(bit & d) {
- if(m != nil)
- mpmodmul(t[j^1], b, m, t[j]);
- else
- mpmul(t[j^1], b, t[j]);
- } else
- j ^= 1;
- }
- if(--i < 0)
- break;
- bit = mpdighi;
- d = e->p[i];
- }
- if(t[j] == res){
- mpfree(t[j^1]);
- } else {
- mpassign(t[j], res);
- mpfree(t[j]);
- }
-
- if(tofree){
- if(tofree & Freeb)
- mpfree(b);
- if(tofree & Freee)
- mpfree(e);
- if(tofree & Freem)
- mpfree(m);
- }
-}
--- a/libmp/mpextendedgcd.c
+++ /dev/null
@@ -1,115 +1,0 @@
-#include "os.h"
-#include <mp.h>
-
-#define iseven(a) (((a)->p[0] & 1) == 0)
-
-// extended binary gcd
-//
-// For a and b it solves, v = gcd(a,b) and finds x and y s.t.
-// ax + by = v
-//
-// Handbook of Applied Cryptography, Menezes et al, 1997, pg 608.
-void
-mpextendedgcd(mpint *a, mpint *b, mpint *v, mpint *x, mpint *y)
-{
- mpint *u, *A, *B, *C, *D;
- int g;
-
- if(v == nil){
- v = mpnew(0);
- mpextendedgcd(a, b, v, x, y);
- mpfree(v);
- return;
- }
- assert(x == nil || (x->flags & MPtimesafe) == 0);
- assert(y == nil || (y->flags & MPtimesafe) == 0);
- assert((a->flags&b->flags) & MPnorm);
- assert(((a->flags|b->flags|v->flags) & MPtimesafe) == 0);
-
- if(a->sign < 0 || b->sign < 0){
- mpassign(mpzero, v);
- mpassign(mpzero, y);
- mpassign(mpzero, x);
- return;
- }
-
- if(a->top == 0){
- mpassign(b, v);
- mpassign(mpone, y);
- mpassign(mpzero, x);
- return;
- }
- if(b->top == 0){
- mpassign(a, v);
- mpassign(mpone, x);
- mpassign(mpzero, y);
- return;
- }
-
- g = 0;
- a = mpcopy(a);
- b = mpcopy(b);
-
- while(iseven(a) && iseven(b)){
- mpright(a, 1, a);
- mpright(b, 1, b);
- g++;
- }
-
- u = mpcopy(a);
- mpassign(b, v);
- A = mpcopy(mpone);
- B = mpcopy(mpzero);
- C = mpcopy(mpzero);
- D = mpcopy(mpone);
-
- for(;;) {
-// print("%B %B %B %B %B %B\n", u, v, A, B, C, D);
- while(iseven(u)){
- mpright(u, 1, u);
- if(!iseven(A) || !iseven(B)) {
- mpadd(A, b, A);
- mpsub(B, a, B);
- }
- mpright(A, 1, A);
- mpright(B, 1, B);
- }
-
-// print("%B %B %B %B %B %B\n", u, v, A, B, C, D);
- while(iseven(v)){
- mpright(v, 1, v);
- if(!iseven(C) || !iseven(D)) {
- mpadd(C, b, C);
- mpsub(D, a, D);
- }
- mpright(C, 1, C);
- mpright(D, 1, D);
- }
-
-// print("%B %B %B %B %B %B\n", u, v, A, B, C, D);
- if(mpcmp(u, v) >= 0){
- mpsub(u, v, u);
- mpsub(A, C, A);
- mpsub(B, D, B);
- } else {
- mpsub(v, u, v);
- mpsub(C, A, C);
- mpsub(D, B, D);
- }
-
- if(u->top == 0)
- break;
-
- }
- mpassign(C, x);
- mpassign(D, y);
- mpleft(v, g, v);
-
- mpfree(A);
- mpfree(B);
- mpfree(C);
- mpfree(D);
- mpfree(u);
- mpfree(a);
- mpfree(b);
-}
--- a/libmp/mpfactorial.c
+++ /dev/null
@@ -1,74 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-mpint*
-mpfactorial(ulong n)
-{
- int i;
- ulong k;
- unsigned cnt;
- int max, mmax;
- mpdigit p, pp[2];
- mpint *r, *s, *stk[31];
-
- cnt = 0;
- max = mmax = -1;
- p = 1;
- r = mpnew(0);
- for(k=2; k<=n; k++){
- pp[0] = 0;
- pp[1] = 0;
- mpvecdigmuladd(&p, 1, (mpdigit)k, pp);
- if(pp[1] == 0) /* !overflow */
- p = pp[0];
- else{
- cnt++;
- if((cnt & 1) == 0){
- s = stk[max];
- mpbits(r, Dbits*(s->top+1+1));
- memset(r->p, 0, Dbytes*(s->top+1+1));
- mpvecmul(s->p, s->top, &p, 1, r->p);
- r->sign = 1;
- r->top = s->top+1+1; /* XXX: norm */
- mpassign(r, s);
- for(i=4; (cnt & (i-1)) == 0; i=i<<1){
- mpmul(stk[max], stk[max-1], r);
- mpassign(r, stk[max-1]);
- max--;
- }
- }else{
- max++;
- if(max > mmax){
- mmax++;
- if(max > nelem(stk))
- abort();
- stk[max] = mpnew(Dbits);
- }
- stk[max]->top = 1;
- stk[max]->p[0] = p;
- }
- p = (mpdigit)k;
- }
- }
- if(max < 0){
- mpbits(r, Dbits);
- r->top = 1;
- r->sign = 1;
- r->p[0] = p;
- }else{
- s = stk[max--];
- mpbits(r, Dbits*(s->top+1+1));
- memset(r->p, 0, Dbytes*(s->top+1+1));
- mpvecmul(s->p, s->top, &p, 1, r->p);
- r->sign = 1;
- r->top = s->top+1+1; /* XXX: norm */
- }
-
- while(max >= 0)
- mpmul(r, stk[max--], r);
- for(max=mmax; max>=0; max--)
- mpfree(stk[max]);
- mpnorm(r);
- return r;
-}
--- a/libmp/mpfield.c
+++ /dev/null
@@ -1,21 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-mpint*
-mpfield(mpint *N)
-{
- Mfield *f;
-
- if(N == nil || N->flags & (MPfield|MPstatic))
- return N;
- if((f = cnfield(N)) != nil)
- goto Exchange;
- if((f = gmfield(N)) != nil)
- goto Exchange;
- return N;
-Exchange:
- setmalloctag(f, getcallerpc(&N));
- mpfree(N);
- return (mpint*)f;
-}
--- a/libmp/mpfmt.c
+++ /dev/null
@@ -1,254 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-static int
-toencx(mpint *b, char *buf, int len, int (*enc)(char*, int, uchar*, int))
-{
- uchar *p;
- int n, rv;
-
- p = nil;
- n = mptobe(b, nil, 0, &p);
- if(n < 0)
- return -1;
- rv = (*enc)(buf, len, p, n);
- free(p);
- return rv;
-}
-
-static int
-topow2(mpint *b, char *buf, int len, int s)
-{
- mpdigit *p, x;
- int i, j, sn;
- char *out, *eout;
-
- if(len < 1)
- return -1;
-
- sn = 1<<s;
- out = buf;
- eout = buf+len;
- for(p = &b->p[b->top-1]; p >= b->p; p--){
- x = *p;
- for(i = Dbits-s; i >= 0; i -= s){
- j = (x >> i) & (sn - 1);
- if(j != 0 || out != buf){
- if(out >= eout)
- return -1;
- *out++ = enc16chr(j);
- }
- }
- }
- if(out == buf)
- *out++ = '0';
- if(out >= eout)
- return -1;
- *out = 0;
- return 0;
-}
-
-static char*
-modbillion(int rem, ulong r, char *out, char *buf)
-{
- ulong rr;
- int i;
-
- for(i = 0; i < 9; i++){
- rr = r%10;
- r /= 10;
- if(out <= buf)
- return nil;
- *--out = '0' + rr;
- if(rem == 0 && r == 0)
- break;
- }
- return out;
-}
-
-static int
-to10(mpint *b, char *buf, int len)
-{
- mpint *d, *r, *billion;
- char *out;
-
- if(len < 1)
- return -1;
-
- d = mpcopy(b);
- d->flags &= ~MPtimesafe;
- mpnorm(d);
- r = mpnew(0);
- billion = uitomp(1000000000, nil);
- out = buf+len;
- *--out = 0;
- do {
- mpdiv(d, billion, d, r);
- out = modbillion(d->top, r->p[0], out, buf);
- if(out == nil)
- break;
- } while(d->top != 0);
- mpfree(d);
- mpfree(r);
- mpfree(billion);
-
- if(out == nil)
- return -1;
- len -= out-buf;
- if(out != buf)
- memmove(buf, out, len);
- return 0;
-}
-
-static int
-to8(mpint *b, char *buf, int len)
-{
- mpdigit x, y;
- char *out;
- int i, j;
-
- if(len < 2)
- return -1;
-
- out = buf+len;
- *--out = 0;
-
- i = j = 0;
- x = y = 0;
- while(j < b->top){
- y = b->p[j++];
- if(i > 0)
- x |= y << i;
- else
- x = y;
- i += Dbits;
- while(i >= 3){
-Digout: i -= 3;
- if(out > buf)
- out--;
- else if(x != 0)
- return -1;
- *out = '0' + (x & 7);
- x = y >> (Dbits-i);
- }
- }
- if(i > 0)
- goto Digout;
-
- while(*out == '0') out++;
- if(*out == '\0')
- *--out = '0';
-
- len -= out-buf;
- if(out != buf)
- memmove(buf, out, len);
- return 0;
-}
-
-int
-mpfmt(Fmt *fmt)
-{
- mpint *b;
- char *x, *p;
- int base;
-
- b = va_arg(fmt->args, mpint*);
- if(b == nil)
- return fmtstrcpy(fmt, "*");
-
- base = fmt->prec;
- if(base == 0)
- base = 16; /* default */
- fmt->flags &= ~FmtPrec;
- p = mptoa(b, base, nil, 0);
- if(p == nil)
- return fmtstrcpy(fmt, "*");
- else{
- if((fmt->flags & FmtSharp) != 0){
- switch(base){
- case 16:
- x = "0x";
- break;
- case 8:
- x = "0";
- break;
- case 2:
- x = "0b";
- break;
- default:
- x = "";
- }
- if(*p == '-')
- fmtprint(fmt, "-%s%s", x, p + 1);
- else
- fmtprint(fmt, "%s%s", x, p);
- }
- else
- fmtstrcpy(fmt, p);
- free(p);
- return 0;
- }
-}
-
-char*
-mptoa(mpint *b, int base, char *buf, int len)
-{
- char *out;
- int rv, alloced;
-
- if(base == 0)
- base = 16; /* default */
- alloced = 0;
- if(buf == nil){
- /* rv <= log₂(base) */
- for(rv=1; (base >> rv) > 1; rv++)
- ;
- len = 10 + (b->top*Dbits / rv);
- buf = malloc(len);
- if(buf == nil)
- return nil;
- alloced = 1;
- }
-
- if(len < 2)
- return nil;
-
- out = buf;
- if(b->sign < 0){
- *out++ = '-';
- len--;
- }
- switch(base){
- case 64:
- rv = toencx(b, out, len, enc64);
- break;
- case 32:
- rv = toencx(b, out, len, enc32);
- break;
- case 16:
- rv = topow2(b, out, len, 4);
- break;
- case 10:
- rv = to10(b, out, len);
- break;
- case 8:
- rv = to8(b, out, len);
- break;
- case 4:
- rv = topow2(b, out, len, 2);
- break;
- case 2:
- rv = topow2(b, out, len, 1);
- break;
- default:
- abort();
- return nil;
- }
- if(rv < 0){
- if(alloced)
- free(buf);
- return nil;
- }
- return buf;
-}
--- a/libmp/mpinvert.c
+++ /dev/null
@@ -1,17 +1,0 @@
-#include "os.h"
-#include <mp.h>
-
-// use extended gcd to find the multiplicative inverse
-// res = b**-1 mod m
-void
-mpinvert(mpint *b, mpint *m, mpint *res)
-{
- mpint *v;
-
- v = mpnew(0);
- mpextendedgcd(b, m, v, res, nil);
- if(mpcmp(v, mpone) != 0)
- abort();
- mpfree(v);
- mpmod(res, m, res);
-}
--- a/libmp/mpleft.c
+++ /dev/null
@@ -1,51 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-// res = b << shift
-void
-mpleft(mpint *b, int shift, mpint *res)
-{
- int d, l, r, i, otop;
- mpdigit this, last;
-
- res->sign = b->sign;
- if(b->top==0){
- res->top = 0;
- return;
- }
-
- // a zero or negative left shift is a right shift
- if(shift <= 0){
- mpright(b, -shift, res);
- return;
- }
-
- // b and res may be the same so remember the old top
- otop = b->top;
-
- // shift
- mpbits(res, otop*Dbits + shift); // overkill
- res->top = DIGITS(otop*Dbits + shift);
- d = shift/Dbits;
- l = shift - d*Dbits;
- r = Dbits - l;
-
- if(l == 0){
- for(i = otop-1; i >= 0; i--)
- res->p[i+d] = b->p[i];
- } else {
- last = 0;
- for(i = otop-1; i >= 0; i--) {
- this = b->p[i];
- res->p[i+d+1] = (last<<l) | (this>>r);
- last = this;
- }
- res->p[d] = last<<l;
- }
- for(i = 0; i < d; i++)
- res->p[i] = 0;
-
- res->flags |= b->flags & MPtimesafe;
- mpnorm(res);
-}
--- a/libmp/mplogic.c
+++ /dev/null
@@ -1,212 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-/*
- mplogic calculates b1|b2 subject to the
- following flag bits (fl)
-
- bit 0: subtract 1 from b1
- bit 1: invert b1
- bit 2: subtract 1 from b2
- bit 3: invert b2
- bit 4: add 1 to output
- bit 5: invert output
-
- it inverts appropriate bits automatically
- depending on the signs of the inputs
-*/
-
-static void
-mplogic(mpint *b1, mpint *b2, mpint *sum, int fl)
-{
- mpint *t;
- mpdigit *dp1, *dp2, *dpo, d1, d2, d;
- int c1, c2, co;
- int i;
-
- assert(((b1->flags | b2->flags | sum->flags) & MPtimesafe) == 0);
- if(b1->sign < 0) fl ^= 0x03;
- if(b2->sign < 0) fl ^= 0x0c;
- sum->sign = (int)(((fl|fl>>2)^fl>>4)<<30)>>31|1;
- if(sum->sign < 0) fl ^= 0x30;
- if(b2->top > b1->top){
- t = b1;
- b1 = b2;
- b2 = t;
- fl = ((fl >> 2) & 0x03) | ((fl << 2) & 0x0c) | (fl & 0x30);
- }
- mpbits(sum, b1->top*Dbits+1);
- dp1 = b1->p;
- dp2 = b2->p;
- dpo = sum->p;
- c1 = fl & 1;
- c2 = fl >> 2 & 1;
- co = fl >> 4 & 1;
- for(i = 0; i < b1->top; i++){
- d1 = dp1[i] - c1;
- if(i < b2->top)
- d2 = dp2[i] - c2;
- else
- d2 = 0;
- if(d1 != (mpdigit)-1) c1 = 0;
- if(d2 != (mpdigit)-1) c2 = 0;
- if((fl & 2) != 0) d1 ^= -1;
- if((fl & 8) != 0) d2 ^= -1;
- d = d1 | d2;
- if((fl & 32) != 0) d ^= -1;
- d += co;
- if(d != 0) co = 0;
- dpo[i] = d;
- }
- sum->top = i;
- if(co)
- dpo[sum->top++] = co;
- mpnorm(sum);
-}
-
-void
-mpor(mpint *b1, mpint *b2, mpint *sum)
-{
- mplogic(b1, b2, sum, 0);
-}
-
-void
-mpand(mpint *b1, mpint *b2, mpint *sum)
-{
- mplogic(b1, b2, sum, 0x2a);
-}
-
-void
-mpbic(mpint *b1, mpint *b2, mpint *sum)
-{
- mplogic(b1, b2, sum, 0x22);
-}
-
-void
-mpnot(mpint *b, mpint *r)
-{
- mpadd(b, mpone, r);
- if(r->top != 0)
- r->sign ^= -2;
-}
-
-void
-mpxor(mpint *b1, mpint *b2, mpint *sum)
-{
- mpint *t;
- mpdigit *dp1, *dp2, *dpo, d1, d2, d;
- int c1, c2, co;
- int i, fl;
-
- assert(((b1->flags | b2->flags | sum->flags) & MPtimesafe) == 0);
- if(b2->top > b1->top){
- t = b1;
- b1 = b2;
- b2 = t;
- }
- fl = (b1->sign & 10) ^ (b2->sign & 12);
- sum->sign = (int)(fl << 28) >> 31 | 1;
- mpbits(sum, b1->top*Dbits+1);
- dp1 = b1->p;
- dp2 = b2->p;
- dpo = sum->p;
- c1 = fl >> 1 & 1;
- c2 = fl >> 2 & 1;
- co = fl >> 3 & 1;
- for(i = 0; i < b1->top; i++){
- d1 = dp1[i] - c1;
- if(i < b2->top)
- d2 = dp2[i] - c2;
- else
- d2 = 0;
- if(d1 != (mpdigit)-1) c1 = 0;
- if(d2 != (mpdigit)-1) c2 = 0;
- d = d1 ^ d2;
- d += co;
- if(d != 0) co = 0;
- dpo[i] = d;
- }
- sum->top = i;
- if(co)
- dpo[sum->top++] = co;
- mpnorm(sum);
-}
-
-void
-mptrunc(mpint *b, int n, mpint *r)
-{
- int d, m, i, c;
-
- assert(((b->flags | r->flags) & MPtimesafe) == 0);
- mpbits(r, n);
- r->top = DIGITS(n);
- d = n / Dbits;
- m = n % Dbits;
- if(b->sign == -1){
- c = 1;
- for(i = 0; i < r->top; i++){
- if(i < b->top)
- r->p[i] = ~(b->p[i] - c);
- else
- r->p[i] = -1;
- if(r->p[i] != 0)
- c = 0;
- }
- if(m != 0)
- r->p[d] &= (1<<m) - 1;
- }else if(b->sign == 1){
- if(d >= b->top){
- mpassign(b, r);
- mpnorm(r);
- return;
- }
- if(b != r)
- for(i = 0; i < d; i++)
- r->p[i] = b->p[i];
- if(m != 0)
- r->p[d] = b->p[d] & ((1<<m)-1);
- }
- r->sign = 1;
- mpnorm(r);
-}
-
-void
-mpxtend(mpint *b, int n, mpint *r)
-{
- int d, m, c, i;
-
- d = (n - 1) / Dbits;
- m = (n - 1) % Dbits;
- if(d >= b->top){
- mpassign(b, r);
- return;
- }
- mptrunc(b, n, r);
- mpbits(r, n);
- if((r->p[d] & 1<<m) == 0){
- mpnorm(r);
- return;
- }
- r->p[d] |= -(1<<m);
- r->sign = -1;
- c = 1;
- for(i = 0; i < r->top; i++){
- r->p[i] = ~(r->p[i] - c);
- if(r->p[i] != 0)
- c = 0;
- }
- mpnorm(r);
-}
-
-void
-mpasr(mpint *b, int n, mpint *r)
-{
- if(b->sign > 0 || n <= 0){
- mpright(b, n, r);
- return;
- }
- mpadd(b, mpone, r);
- mpright(r, n, r);
- mpsub(r, mpone, r);
-}
--- a/libmp/mpmod.c
+++ /dev/null
@@ -1,20 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-void
-mpmod(mpint *x, mpint *n, mpint *r)
-{
- int sign;
- mpint *ns;
-
- sign = x->sign;
- ns = sign < 0 && n == r ? mpcopy(n) : n;
- if((n->flags & MPfield) == 0
- || ((Mfield*)n)->reduce((Mfield*)n, x, r) != 0)
- mpdiv(x, n, nil, r);
- if(sign < 0){
- mpmagsub(ns, r, r);
- if(ns != n) mpfree(ns);
- }
-}
--- a/libmp/mpmodop.c
+++ /dev/null
@@ -1,95 +1,0 @@
-#include "os.h"
-#include <mp.h>
-
-/* operands need to have m->top+1 digits of space and satisfy 0 ≤ a ≤ m-1 */
-static mpint*
-modarg(mpint *a, mpint *m)
-{
- if(a->size <= m->top || a->sign < 0 || mpmagcmp(a, m) >= 0){
- a = mpcopy(a);
- mpmod(a, m, a);
- mpbits(a, Dbits*(m->top+1));
- a->top = m->top;
- } else if(a->top < m->top){
- memset(&a->p[a->top], 0, (m->top - a->top)*Dbytes);
- }
- return a;
-}
-
-void
-mpmodadd(mpint *b1, mpint *b2, mpint *m, mpint *sum)
-{
- mpint *a, *b;
- mpdigit d;
- int i, j;
-
- a = modarg(b1, m);
- b = modarg(b2, m);
-
- sum->flags |= (a->flags | b->flags) & MPtimesafe;
- mpbits(sum, Dbits*2*(m->top+1));
-
- mpvecadd(a->p, m->top, b->p, m->top, sum->p);
- mpvecsub(sum->p, m->top+1, m->p, m->top, sum->p+m->top+1);
-
- d = sum->p[2*m->top+1];
- for(i = 0, j = m->top+1; i < m->top; i++, j++)
- sum->p[i] = (sum->p[i] & d) | (sum->p[j] & ~d);
-
- sum->top = m->top;
- sum->sign = 1;
- mpnorm(sum);
-
- if(a != b1)
- mpfree(a);
- if(b != b2)
- mpfree(b);
-}
-
-void
-mpmodsub(mpint *b1, mpint *b2, mpint *m, mpint *diff)
-{
- mpint *a, *b;
- mpdigit d;
- int i, j;
-
- a = modarg(b1, m);
- b = modarg(b2, m);
-
- diff->flags |= (a->flags | b->flags) & MPtimesafe;
- mpbits(diff, Dbits*2*(m->top+1));
-
- a->p[m->top] = 0;
- mpvecsub(a->p, m->top+1, b->p, m->top, diff->p);
- mpvecadd(diff->p, m->top, m->p, m->top, diff->p+m->top+1);
-
- d = ~diff->p[m->top];
- for(i = 0, j = m->top+1; i < m->top; i++, j++)
- diff->p[i] = (diff->p[i] & d) | (diff->p[j] & ~d);
-
- diff->top = m->top;
- diff->sign = 1;
- mpnorm(diff);
-
- if(a != b1)
- mpfree(a);
- if(b != b2)
- mpfree(b);
-}
-
-void
-mpmodmul(mpint *b1, mpint *b2, mpint *m, mpint *prod)
-{
- mpint *a, *b;
-
- a = modarg(b1, m);
- b = modarg(b2, m);
-
- mpmul(a, b, prod);
- mpmod(prod, m, prod);
-
- if(a != b1)
- mpfree(a);
- if(b != b2)
- mpfree(b);
-}
--- a/libmp/mpmul.c
+++ /dev/null
@@ -1,176 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-//
-// from knuth's 1969 seminumberical algorithms, pp 233-235 and pp 258-260
-//
-// mpvecmul is an assembly language routine that performs the inner
-// loop.
-//
-// the karatsuba trade off is set empiricly by measuring the algs on
-// a 400 MHz Pentium II.
-//
-
-// karatsuba like (see knuth pg 258)
-// prereq: p is already zeroed
-static void
-mpkaratsuba(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *p)
-{
- mpdigit *t, *u0, *u1, *v0, *v1, *u0v0, *u1v1, *res, *diffprod;
- int u0len, u1len, v0len, v1len, reslen;
- int sign, n;
-
- // divide each piece in half
- n = alen/2;
- if(alen&1)
- n++;
- u0len = n;
- u1len = alen-n;
- if(blen > n){
- v0len = n;
- v1len = blen-n;
- } else {
- v0len = blen;
- v1len = 0;
- }
- u0 = a;
- u1 = a + u0len;
- v0 = b;
- v1 = b + v0len;
-
- // room for the partial products
- t = mallocz(Dbytes*5*(2*n+1), 1);
- if(t == nil)
- sysfatal("mpkaratsuba: %r");
- u0v0 = t;
- u1v1 = t + (2*n+1);
- diffprod = t + 2*(2*n+1);
- res = t + 3*(2*n+1);
- reslen = 4*n+1;
-
- // t[0] = (u1-u0)
- sign = 1;
- if(mpveccmp(u1, u1len, u0, u0len) < 0){
- sign = -1;
- mpvecsub(u0, u0len, u1, u1len, u0v0);
- } else
- mpvecsub(u1, u1len, u0, u1len, u0v0);
-
- // t[1] = (v0-v1)
- if(mpveccmp(v0, v0len, v1, v1len) < 0){
- sign *= -1;
- mpvecsub(v1, v1len, v0, v1len, u1v1);
- } else
- mpvecsub(v0, v0len, v1, v1len, u1v1);
-
- // t[4:5] = (u1-u0)*(v0-v1)
- mpvecmul(u0v0, u0len, u1v1, v0len, diffprod);
-
- // t[0:1] = u1*v1
- memset(t, 0, 2*(2*n+1)*Dbytes);
- if(v1len > 0)
- mpvecmul(u1, u1len, v1, v1len, u1v1);
-
- // t[2:3] = u0v0
- mpvecmul(u0, u0len, v0, v0len, u0v0);
-
- // res = u0*v0<<n + u0*v0
- mpvecadd(res, reslen, u0v0, u0len+v0len, res);
- mpvecadd(res+n, reslen-n, u0v0, u0len+v0len, res+n);
-
- // res += u1*v1<<n + u1*v1<<2*n
- if(v1len > 0){
- mpvecadd(res+n, reslen-n, u1v1, u1len+v1len, res+n);
- mpvecadd(res+2*n, reslen-2*n, u1v1, u1len+v1len, res+2*n);
- }
-
- // res += (u1-u0)*(v0-v1)<<n
- if(sign < 0)
- mpvecsub(res+n, reslen-n, diffprod, u0len+v0len, res+n);
- else
- mpvecadd(res+n, reslen-n, diffprod, u0len+v0len, res+n);
- memmove(p, res, (alen+blen)*Dbytes);
-
- free(t);
-}
-
-#define KARATSUBAMIN 32
-
-void
-mpvecmul(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *p)
-{
- int i;
- mpdigit d;
- mpdigit *t;
-
- // both mpvecdigmuladd and karatsuba are fastest when a is the longer vector
- if(alen < blen){
- i = alen;
- alen = blen;
- blen = i;
- t = a;
- a = b;
- b = t;
- }
-
- if(alen >= KARATSUBAMIN && blen > 1){
- // O(n^1.585)
- mpkaratsuba(a, alen, b, blen, p);
- } else {
- // O(n^2)
- for(i = 0; i < blen; i++){
- d = b[i];
- if(d != 0)
- mpvecdigmuladd(a, alen, d, &p[i]);
- }
- }
-}
-
-void
-mpvectsmul(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *p)
-{
- int i;
- mpdigit *t;
-
- if(alen < blen){
- i = alen;
- alen = blen;
- blen = i;
- t = a;
- a = b;
- b = t;
- }
- if(blen == 0)
- return;
- for(i = 0; i < blen; i++)
- mpvecdigmuladd(a, alen, b[i], &p[i]);
-}
-
-void
-mpmul(mpint *b1, mpint *b2, mpint *prod)
-{
- mpint *oprod;
-
- oprod = prod;
- if(prod == b1 || prod == b2){
- prod = mpnew(0);
- prod->flags = oprod->flags;
- }
- prod->flags |= (b1->flags | b2->flags) & MPtimesafe;
-
- prod->top = 0;
- mpbits(prod, (b1->top+b2->top+1)*Dbits);
- if(prod->flags & MPtimesafe)
- mpvectsmul(b1->p, b1->top, b2->p, b2->top, prod->p);
- else
- mpvecmul(b1->p, b1->top, b2->p, b2->top, prod->p);
- prod->top = b1->top+b2->top+1;
- prod->sign = b1->sign*b2->sign;
- mpnorm(prod);
-
- if(oprod != prod){
- mpassign(prod, oprod);
- mpfree(prod);
- }
-}
--- a/libmp/mpnrand.c
+++ /dev/null
@@ -1,23 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-/* return uniform random [0..n-1] */
-mpint*
-mpnrand(mpint *n, void (*gen)(uchar*, int), mpint *b)
-{
- int bits;
-
- bits = mpsignif(n);
- if(bits == 0)
- abort();
- if(b == nil){
- b = mpnew(bits);
- setmalloctag(b, getcallerpc(&n));
- }
- do {
- mprand(bits, gen, b);
- } while(mpmagcmp(b, n) >= 0);
-
- return b;
-}
--- a/libmp/mprand.c
+++ /dev/null
@@ -1,25 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-mpint*
-mprand(int bits, void (*gen)(uchar*, int), mpint *b)
-{
- mpdigit mask;
-
- if(b == nil){
- b = mpnew(bits);
- setmalloctag(b, getcallerpc(&bits));
- }else
- mpbits(b, bits);
-
- b->sign = 1;
- b->top = DIGITS(bits);
- (*gen)((uchar*)b->p, b->top*Dbytes);
-
- mask = ((mpdigit)1 << (bits%Dbits))-1;
- if(mask != 0)
- b->p[b->top-1] &= mask;
-
- return mpnorm(b);
-}
--- a/libmp/mpright.c
+++ /dev/null
@@ -1,57 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-// res = b >> shift
-void
-mpright(mpint *b, int shift, mpint *res)
-{
- int d, l, r, i;
- mpdigit this, last;
-
- res->sign = b->sign;
- if(b->top==0){
- res->top = 0;
- return;
- }
-
- // a negative right shift is a left shift
- if(shift < 0){
- mpleft(b, -shift, res);
- return;
- }
-
- if(res != b)
- mpbits(res, b->top*Dbits - shift);
- else if(shift == 0)
- return;
-
- d = shift/Dbits;
- r = shift - d*Dbits;
- l = Dbits - r;
-
- // shift all the bits out == zero
- if(d>=b->top){
- res->sign = 1;
- res->top = 0;
- return;
- }
-
- // special case digit shifts
- if(r == 0){
- for(i = 0; i < b->top-d; i++)
- res->p[i] = b->p[i+d];
- } else {
- last = b->p[d];
- for(i = 0; i < b->top-d-1; i++){
- this = b->p[i+d+1];
- res->p[i] = (this<<l) | (last>>r);
- last = this;
- }
- res->p[i++] = last>>r;
- }
-
- res->top = i;
- res->flags |= b->flags & MPtimesafe;
- mpnorm(res);
-}
--- a/libmp/mpsel.c
+++ /dev/null
@@ -1,42 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-// res = s != 0 ? b1 : b2
-void
-mpsel(int s, mpint *b1, mpint *b2, mpint *res)
-{
- mpdigit d;
- int n, m, i;
-
- res->flags |= (b1->flags | b2->flags) & MPtimesafe;
- if((res->flags & MPtimesafe) == 0){
- mpassign(s ? b1 : b2, res);
- return;
- }
- res->flags &= ~MPnorm;
-
- n = b1->top;
- m = b2->top;
- mpbits(res, Dbits*(n >= m ? n : m));
- res->top = n >= m ? n : m;
-
- s = ((-s^s)|s)>>(sizeof(s)*8-1);
- res->sign = (b1->sign & s) | (b2->sign & ~s);
-
- d = -((mpdigit)s & 1);
-
- i = 0;
- while(i < n && i < m){
- res->p[i] = (b1->p[i] & d) | (b2->p[i] & ~d);
- i++;
- }
- while(i < n){
- res->p[i] = b1->p[i] & d;
- i++;
- }
- while(i < m){
- res->p[i] = b2->p[i] & ~d;
- i++;
- }
-}
--- a/libmp/mpsub.c
+++ /dev/null
@@ -1,56 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-// diff = abs(b1) - abs(b2), i.e., subtract the magnitudes
-void
-mpmagsub(mpint *b1, mpint *b2, mpint *diff)
-{
- int n, m, sign;
- mpint *t;
-
- // get the sizes right
- if(mpmagcmp(b1, b2) < 0){
- assert(((b1->flags | b2->flags | diff->flags) & MPtimesafe) == 0);
- sign = -1;
- t = b1;
- b1 = b2;
- b2 = t;
- } else {
- diff->flags |= (b1->flags | b2->flags) & MPtimesafe;
- sign = 1;
- }
- n = b1->top;
- m = b2->top;
- if(m == 0){
- mpassign(b1, diff);
- diff->sign = sign;
- return;
- }
- mpbits(diff, n*Dbits);
-
- mpvecsub(b1->p, n, b2->p, m, diff->p);
- diff->sign = sign;
- diff->top = n;
- mpnorm(diff);
-}
-
-// diff = b1 - b2
-void
-mpsub(mpint *b1, mpint *b2, mpint *diff)
-{
- int sign;
-
- if(b1->sign != b2->sign){
- assert(((b1->flags | b2->flags | diff->flags) & MPtimesafe) == 0);
- sign = b1->sign;
- mpmagadd(b1, b2, diff);
- diff->sign = sign;
- return;
- }
-
- sign = b1->sign;
- mpmagsub(b1, b2, diff);
- if(diff->top != 0)
- diff->sign *= sign;
-}
--- a/libmp/mptobe.c
+++ /dev/null
@@ -1,32 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-// convert an mpint into a big endian byte array (most significant byte first; left adjusted)
-// return number of bytes converted
-// if p == nil, allocate and result array
-int
-mptobe(mpint *b, uchar *p, uint n, uchar **pp)
-{
- int m;
-
- m = (mpsignif(b)+7)/8;
- if(m == 0)
- m++;
- if(p == nil){
- n = m;
- p = malloc(n);
- if(p == nil)
- sysfatal("mptobe: %r");
- setmalloctag(p, getcallerpc(&b));
- } else {
- if(n < m)
- return -1;
- if(n > m)
- memset(p+m, 0, n-m);
- }
- if(pp != nil)
- *pp = p;
- mptober(b, p, m);
- return m;
-}
--- a/libmp/mptober.c
+++ /dev/null
@@ -1,34 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-void
-mptober(mpint *b, uchar *p, int n)
-{
- int i, j, m;
- mpdigit x;
-
- memset(p, 0, n);
-
- p += n;
- m = b->top*Dbytes;
- if(m < n)
- n = m;
-
- i = 0;
- while(n >= Dbytes){
- n -= Dbytes;
- x = b->p[i++];
- for(j = 0; j < Dbytes; j++){
- *--p = x;
- x >>= 8;
- }
- }
- if(n > 0){
- x = b->p[i];
- for(j = 0; j < n; j++){
- *--p = x;
- x >>= 8;
- }
- }
-}
--- a/libmp/mptoi.c
+++ /dev/null
@@ -1,44 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-/*
- * this code assumes that mpdigit is at least as
- * big as an int.
- */
-
-mpint*
-itomp(int i, mpint *b)
-{
- if(b == nil){
- b = mpnew(0);
- setmalloctag(b, getcallerpc(&i));
- }
- b->sign = (i >> (sizeof(i)*8 - 1)) | 1;
- i *= b->sign;
- *b->p = i;
- b->top = 1;
- return mpnorm(b);
-}
-
-int
-mptoi(mpint *b)
-{
- uint x;
-
- if(b->top==0)
- return 0;
- x = *b->p;
- if(b->sign > 0){
- if(b->top > 1 || (x > MAXINT))
- x = (int)MAXINT;
- else
- x = (int)x;
- } else {
- if(b->top > 1 || x > MAXINT+1)
- x = (int)MININT;
- else
- x = -(int)x;
- }
- return x;
-}
--- a/libmp/mptole.c
+++ /dev/null
@@ -1,28 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-// convert an mpint into a little endian byte array (least significant byte first)
-// return number of bytes converted
-// if p == nil, allocate and result array
-int
-mptole(mpint *b, uchar *p, uint n, uchar **pp)
-{
- int m;
-
- m = (mpsignif(b)+7)/8;
- if(m == 0)
- m++;
- if(p == nil){
- n = m;
- p = malloc(n);
- if(p == nil)
- sysfatal("mptole: %r");
- setmalloctag(p, getcallerpc(&b));
- } else if(n < m)
- return -1;
- if(pp != nil)
- *pp = p;
- mptolel(b, p, n);
- return m;
-}
--- a/libmp/mptolel.c
+++ /dev/null
@@ -1,33 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-void
-mptolel(mpint *b, uchar *p, int n)
-{
- int i, j, m;
- mpdigit x;
-
- memset(p, 0, n);
-
- m = b->top*Dbytes;
- if(m < n)
- n = m;
-
- i = 0;
- while(n >= Dbytes){
- n -= Dbytes;
- x = b->p[i++];
- for(j = 0; j < Dbytes; j++){
- *p++ = x;
- x >>= 8;
- }
- }
- if(n > 0){
- x = b->p[i];
- for(j = 0; j < n; j++){
- *p++ = x;
- x >>= 8;
- }
- }
-}
--- a/libmp/mptoui.c
+++ /dev/null
@@ -1,34 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-/*
- * this code assumes that mpdigit is at least as
- * big as an int.
- */
-
-mpint*
-uitomp(uint i, mpint *b)
-{
- if(b == nil){
- b = mpnew(0);
- setmalloctag(b, getcallerpc(&i));
- }
- *b->p = i;
- b->top = 1;
- b->sign = 1;
- return mpnorm(b);
-}
-
-uint
-mptoui(mpint *b)
-{
- uint x;
-
- x = *b->p;
- if(b->sign < 0)
- x = 0;
- else if(b->top > 1 || (sizeof(mpdigit) > sizeof(uint) && x > MAXUINT))
- x = MAXUINT;
- return x;
-}
--- a/libmp/mptouv.c
+++ /dev/null
@@ -1,47 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-#define VLDIGITS (sizeof(vlong)/sizeof(mpdigit))
-
-/*
- * this code assumes that a vlong is an integral number of
- * mpdigits long.
- */
-mpint*
-uvtomp(uvlong v, mpint *b)
-{
- int s;
-
- if(b == nil){
- b = mpnew(VLDIGITS*Dbits);
- setmalloctag(b, getcallerpc(&v));
- }else
- mpbits(b, VLDIGITS*Dbits);
- b->sign = 1;
- for(s = 0; s < VLDIGITS; s++){
- b->p[s] = v;
- v >>= sizeof(mpdigit)*8;
- }
- b->top = s;
- return mpnorm(b);
-}
-
-uvlong
-mptouv(mpint *b)
-{
- uvlong v;
- int s;
-
- if(b->top == 0 || b->sign < 0)
- return 0LL;
-
- if(b->top > VLDIGITS)
- return -1LL;
-
- v = 0ULL;
- for(s = 0; s < b->top; s++)
- v |= (uvlong)b->p[s]<<(s*sizeof(mpdigit)*8);
-
- return v;
-}
--- a/libmp/mptov.c
+++ /dev/null
@@ -1,63 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-#define VLDIGITS (sizeof(vlong)/sizeof(mpdigit))
-
-/*
- * this code assumes that a vlong is an integral number of
- * mpdigits long.
- */
-mpint*
-vtomp(vlong v, mpint *b)
-{
- int s;
- uvlong uv;
-
- if(b == nil){
- b = mpnew(VLDIGITS*Dbits);
- setmalloctag(b, getcallerpc(&v));
- }else
- mpbits(b, VLDIGITS*Dbits);
- b->sign = (v >> (sizeof(v)*8 - 1)) | 1;
- uv = v * b->sign;
- for(s = 0; s < VLDIGITS; s++){
- b->p[s] = uv;
- uv >>= sizeof(mpdigit)*8;
- }
- b->top = s;
- return mpnorm(b);
-}
-
-vlong
-mptov(mpint *b)
-{
- uvlong v;
- int s;
-
- if(b->top == 0)
- return 0LL;
-
- if(b->top > VLDIGITS){
- if(b->sign > 0)
- return (vlong)MAXVLONG;
- else
- return (vlong)MINVLONG;
- }
-
- v = 0ULL;
- for(s = 0; s < b->top; s++)
- v |= (uvlong)b->p[s]<<(s*sizeof(mpdigit)*8);
-
- if(b->sign > 0){
- if(v > MAXVLONG)
- v = MAXVLONG;
- } else {
- if(v > MINVLONG)
- v = MINVLONG;
- else
- v = -(vlong)v;
- }
-
- return (vlong)v;
-}
--- a/libmp/mpvecadd.c
+++ /dev/null
@@ -1,35 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-// prereq: alen >= blen, sum has at least blen+1 digits
-void
-mpvecadd(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *sum)
-{
- int i, carry;
- mpdigit x, y;
-
- carry = 0;
- for(i = 0; i < blen; i++){
- x = *a++;
- y = *b++;
- x += carry;
- if(x < carry)
- carry = 1;
- else
- carry = 0;
- x += y;
- if(x < y)
- carry++;
- *sum++ = x;
- }
- for(; i < alen; i++){
- x = *a++ + carry;
- if(x < carry)
- carry = 1;
- else
- carry = 0;
- *sum++ = x;
- }
- *sum = carry;
-}
--- a/libmp/mpveccmp.c
+++ /dev/null
@@ -1,27 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-int
-mpveccmp(mpdigit *a, int alen, mpdigit *b, int blen)
-{
- mpdigit x;
-
- while(alen > blen)
- if(a[--alen] != 0)
- return 1;
- while(blen > alen)
- if(b[--blen] != 0)
- return -1;
- while(alen > 0){
- --alen;
- x = a[alen] - b[alen];
- if(x == 0)
- continue;
- if(x > a[alen])
- return -1;
- else
- return 1;
- }
- return 0;
-}
--- a/libmp/mpvecdigmuladd.c
+++ /dev/null
@@ -1,103 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-#define LO(x) ((x) & ((1<<(Dbits/2))-1))
-#define HI(x) ((x) >> (Dbits/2))
-
-static void
-mpdigmul(mpdigit a, mpdigit b, mpdigit *p)
-{
- mpdigit x, ah, al, bh, bl, p1, p2, p3, p4;
- int carry;
-
- // half digits
- ah = HI(a);
- al = LO(a);
- bh = HI(b);
- bl = LO(b);
-
- // partial products
- p1 = ah*bl;
- p2 = bh*al;
- p3 = bl*al;
- p4 = ah*bh;
-
- // p = ((p1+p2)<<(Dbits/2)) + (p4<<Dbits) + p3
- carry = 0;
- x = p1<<(Dbits/2);
- p3 += x;
- if(p3 < x)
- carry++;
- x = p2<<(Dbits/2);
- p3 += x;
- if(p3 < x)
- carry++;
- p4 += carry + HI(p1) + HI(p2); // can't carry out of the high digit
- p[0] = p3;
- p[1] = p4;
-}
-
-// prereq: p must have room for n+1 digits
-void
-mpvecdigmuladd(mpdigit *b, int n, mpdigit m, mpdigit *p)
-{
- int i;
- mpdigit carry, x, y, part[2];
-
- carry = 0;
- part[1] = 0;
- for(i = 0; i < n; i++){
- x = part[1] + carry;
- if(x < carry)
- carry = 1;
- else
- carry = 0;
- y = *p;
- mpdigmul(*b++, m, part);
- x += part[0];
- if(x < part[0])
- carry++;
- x += y;
- if(x < y)
- carry++;
- *p++ = x;
- }
- *p = part[1] + carry;
-}
-
-// prereq: p must have room for n+1 digits
-int
-mpvecdigmulsub(mpdigit *b, int n, mpdigit m, mpdigit *p)
-{
- int i;
- mpdigit x, y, part[2], borrow;
-
- borrow = 0;
- part[1] = 0;
- for(i = 0; i < n; i++){
- x = *p;
- y = x - borrow;
- if(y > x)
- borrow = 1;
- else
- borrow = 0;
- x = part[1];
- mpdigmul(*b++, m, part);
- x += part[0];
- if(x < part[0])
- borrow++;
- x = y - x;
- if(x > y)
- borrow++;
- *p++ = x;
- }
-
- x = *p;
- y = x - borrow - part[1];
- *p = y;
- if(y > x)
- return -1;
- else
- return 1;
-}
--- a/libmp/mpvecsub.c
+++ /dev/null
@@ -1,34 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-// prereq: a >= b, alen >= blen, diff has at least alen digits
-void
-mpvecsub(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *diff)
-{
- int i, borrow;
- mpdigit x, y;
-
- borrow = 0;
- for(i = 0; i < blen; i++){
- x = *a++;
- y = *b++;
- y += borrow;
- if(y < borrow)
- borrow = 1;
- else
- borrow = 0;
- if(x < y)
- borrow++;
- *diff++ = x - y;
- }
- for(; i < alen; i++){
- x = *a++;
- y = x - borrow;
- if(y > x)
- borrow = 1;
- else
- borrow = 0;
- *diff++ = y;
- }
-}
--- a/libmp/mpvectscmp.c
+++ /dev/null
@@ -1,34 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-int
-mpvectscmp(mpdigit *a, int alen, mpdigit *b, int blen)
-{
- mpdigit x, y, z, v;
- int m, p;
-
- if(alen > blen){
- v = 0;
- while(alen > blen)
- v |= a[--alen];
- m = p = ((-v^v)|v)>>(Dbits-1);
- } else if(blen > alen){
- v = 0;
- while(blen > alen)
- v |= b[--blen];
- m = ((-v^v)|v)>>(Dbits-1);
- p = m^1;
- } else
- m = p = 0;
- while(alen-- > 0){
- x = a[alen];
- y = b[alen];
- z = x - y;
- x = ~x;
- v = (((-z^z)|z)>>(Dbits-1)) & ~m;
- p = ((~((x&y)|(x&z)|(y&z))>>(Dbits-1)) & v) | (p & ~v);
- m |= v;
- }
- return (p-m) | m;
-}
--- a/libmp/os.h
+++ /dev/null
@@ -1,3 +1,0 @@
-#include <u.h>
-#include <libc.h>
-
--- a/libmp/reduce
+++ /dev/null
@@ -1,16 +1,0 @@
-O=$1
-shift
-objtype=$1
-shift
-
-ls -p ../$objtype/*.[cs] >[2]/dev/null | sed 's/..$//' > /tmp/reduce.$pid
-#
-# if empty directory, just return the input files
-#
-if (! ~ $status '|') {
- echo $*
- rm /tmp/reduce.$pid
- exit 0
-}
-echo $* | tr ' ' \012 | grep -v -f /tmp/reduce.$pid | tr \012 ' '
-rm /tmp/reduce.$pid
--- a/libmp/strtomp.c
+++ /dev/null
@@ -1,206 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include "dat.h"
-
-static char*
-frompow2(char *a, mpint *b, int s)
-{
- char *p, *next;
- mpdigit x;
- int i;
-
- i = 1<<s;
- for(p = a; (dec16chr(*p) & 255) < i; p++)
- ;
-
- mpbits(b, (p-a)*s);
- b->top = 0;
- next = p;
-
- while(p > a){
- x = 0;
- for(i = 0; i < Dbits; i += s){
- if(p <= a)
- break;
- x |= dec16chr(*--p)<<i;
- }
- b->p[b->top++] = x;
- }
- return next;
-}
-
-static char*
-from8(char *a, mpint *b)
-{
- char *p, *next;
- mpdigit x, y;
- int i;
-
- for(p = a; ((*p - '0') & 255) < 8; p++)
- ;
-
- mpbits(b, (p-a)*3);
- b->top = 0;
- next = p;
-
- i = 0;
- x = y = 0;
- while(p > a){
- y = *--p - '0';
- x |= y << i;
- i += 3;
- if(i >= Dbits){
-Digout:
- i -= Dbits;
- b->p[b->top++] = x;
- x = y >> (3-i);
- }
- }
- if(i > 0)
- goto Digout;
-
- return next;
-}
-
-static ulong mppow10[] = {
- 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
-};
-
-static char*
-from10(char *a, mpint *b)
-{
- ulong x, y;
- mpint *pow, *r;
- int i;
-
- pow = mpnew(0);
- r = mpnew(0);
-
- b->top = 0;
- for(;;){
- // do a billion at a time in native arithmetic
- x = 0;
- for(i = 0; i < 9; i++){
- y = *a - '0';
- if(y > 9)
- break;
- a++;
- x *= 10;
- x += y;
- }
- if(i == 0)
- break;
-
- // accumulate into mpint
- uitomp(mppow10[i], pow);
- uitomp(x, r);
- mpmul(b, pow, b);
- mpadd(b, r, b);
- if(i < 9)
- break;
- }
- mpfree(pow);
- mpfree(r);
- return a;
-}
-
-static char*
-fromdecx(char *a, mpint *b, int (*chr)(int), int (*dec)(uchar*, int, char*, int))
-{
- char *buf = a;
- uchar *p;
- int n, m;
-
- b->top = 0;
- for(; (*chr)(*a) >= 0; a++)
- ;
- n = a-buf;
- if(n > 0){
- p = malloc(n);
- if(p == nil)
- sysfatal("malloc: %r");
- m = (*dec)(p, n, buf, n);
- if(m > 0)
- betomp(p, m, b);
- free(p);
- }
- return a;
-}
-
-mpint*
-strtomp(char *a, char **pp, int base, mpint *b)
-{
- int sign;
- char *e;
-
- if(b == nil){
- b = mpnew(0);
- setmalloctag(b, getcallerpc(&a));
- }
-
- while(*a==' ' || *a=='\t')
- a++;
-
- sign = 1;
- for(;; a++){
- switch(*a){
- case '-':
- sign *= -1;
- continue;
- }
- break;
- }
-
- if(base == 0){
- base = 10;
- if(a[0] == '0'){
- if(a[1] == 'x' || a[1] == 'X') {
- a += 2;
- base = 16;
- } else if(a[1] == 'b' || a[1] == 'B') {
- a += 2;
- base = 2;
- } else if(a[1] >= '0' && a[1] <= '7') {
- a++;
- base = 8;
- }
- }
- }
-
- switch(base){
- case 2:
- e = frompow2(a, b, 1);
- break;
- case 4:
- e = frompow2(a, b, 2);
- break;
- case 8:
- e = from8(a, b);
- break;
- case 10:
- e = from10(a, b);
- break;
- case 16:
- e = frompow2(a, b, 4);
- break;
- case 32:
- e = fromdecx(a, b, dec32chr, dec32);
- break;
- case 64:
- e = fromdecx(a, b, dec64chr, dec64);
- break;
- default:
- abort();
- return nil;
- }
-
- if(pp != nil)
- *pp = e;
-
- // if no characters parsed, there wasn't a number to convert
- if(e == a)
- return nil;
-
- b->sign = sign;
- return mpnorm(b);
-}
--- a/libsec/Makefile
+++ /dev/null
@@ -1,28 +1,0 @@
-ROOT=..
-include ../Make.config
-LIB=libsec.a
-
-OFILES=\
- aes.$O aesni.$O aesCBC.$O aes_gcm.$O\
- poly1305.$O chacha.$O chachablock.$O ccpoly.$O\
- des.$O des3CBC.$O desmodes.$O\
- ecc.$O jacobian.$O secp256k1.$O secp256r1.$O secp384r1.$O\
- curve25519.$O curve25519_dh.$O\
- genrandom.$O fastrand.$O nfastrand.$O prng.$O\
- hmac.$O hkdf.$O pbkdf2.$O\
- rsaalloc.$O rsadecrypt.$O rsaencrypt.$O\
- dh.$O\
- rc4.$O md5.$O md5block.$O\
- sha1.$O sha2_128.$O sha2_64.$O\
- sha1block.$O sha2block128.$O sha2block64.$O\
- tlshand.$O x509.$O\
- tsmemcmp.$O\
-
-default: $(LIB)
-$(LIB): $(OFILES)
- $(AR) r $(LIB) $(OFILES)
- $(RANLIB) $(LIB)
-
-%.$O: %.c
- $(CC) $(CFLAGS) $*.c
-
--- a/libsec/aes.c
+++ /dev/null
@@ -1,1257 +1,0 @@
-/*
- * this code is derived from the following source,
- * and modified to fit into the plan 9 libsec interface.
- * most of the changes are confined to the top section,
- * with the exception of converting Te4 and Td4 into u8 rather than u32 arrays.
- *
- * rijndael-alg-fst.c
- *
- * @version 3.0 (December 2000)
- *
- * Optimised ANSI C code for the Rijndael cipher (now AES)
- *
- * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
- * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
- * @author Paulo Barreto <paulo.barreto@terra.com.br>
- *
- * This code is hereby placed in the public domain.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "os.h"
-#include <libsec.h>
-
-typedef uchar u8;
-typedef ulong u32;
-
-#define GETU32(pt) (((u32)(pt)[0]<<24) ^ ((u32)(pt)[1]<<16) ^ \
- ((u32)(pt)[2]<< 8) ^ ((u32)(pt)[3]))
-#define PUTU32(ct, st) { (ct)[0] = (u8)((st)>>24); (ct)[1] = (u8)((st)>>16); \
- (ct)[2] = (u8)((st)>> 8); (ct)[3] = (u8)(st); }
-
-#define FULL_UNROLL
-
-/*
-Te0[x] = S [x].[02, 01, 01, 03];
-Te1[x] = S [x].[03, 02, 01, 01];
-Te2[x] = S [x].[01, 03, 02, 01];
-Te3[x] = S [x].[01, 01, 03, 02];
-Te4[x] = S [x]
-
-Td0[x] = Si[x].[0e, 09, 0d, 0b];
-Td1[x] = Si[x].[0b, 0e, 09, 0d];
-Td2[x] = Si[x].[0d, 0b, 0e, 09];
-Td3[x] = Si[x].[09, 0d, 0b, 0e];
-Td4[x] = Si[x]
-*/
-
-static u32 Te0[256] = {
- 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
- 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
- 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
- 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
- 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
- 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
- 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
- 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
- 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
- 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
- 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
- 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
- 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
- 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
- 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
- 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
- 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
- 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
- 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
- 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
- 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
- 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
- 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
- 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
- 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
- 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
- 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
- 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
- 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
- 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
- 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
- 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
- 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
- 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
- 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
- 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
- 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
- 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
- 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
- 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
- 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
- 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
- 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
- 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
- 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
- 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
- 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
- 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
- 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
- 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
- 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
- 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
- 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
- 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
- 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
- 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
- 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
- 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
- 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
- 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
- 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
- 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
- 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
- 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
-};
-static u32 Te1[256] = {
- 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
- 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
- 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
- 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
- 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
- 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
- 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
- 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
- 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
- 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
- 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
- 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
- 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
- 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
- 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
- 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
- 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
- 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
- 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
- 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
- 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
- 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
- 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
- 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
- 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
- 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
- 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
- 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
- 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
- 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
- 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
- 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
- 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
- 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
- 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
- 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
- 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
- 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
- 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
- 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
- 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
- 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
- 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
- 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
- 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
- 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
- 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
- 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
- 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
- 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
- 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
- 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
- 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
- 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
- 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
- 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
- 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
- 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
- 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
- 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
- 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
- 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
- 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
- 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
-};
-static u32 Te2[256] = {
- 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
- 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
- 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
- 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
- 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
- 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
- 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
- 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
- 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
- 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
- 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
- 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
- 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
- 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
- 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
- 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
- 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
- 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
- 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
- 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
- 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
- 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
- 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
- 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
- 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
- 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
- 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
- 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
- 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
- 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
- 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
- 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
- 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
- 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
- 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
- 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
- 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
- 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
- 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
- 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
- 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
- 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
- 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
- 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
- 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
- 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
- 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
- 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
- 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
- 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
- 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
- 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
- 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
- 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
- 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
- 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
- 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
- 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
- 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
- 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
- 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
- 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
- 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
- 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
-};
-static u32 Te3[256] = {
-
- 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
- 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
- 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
- 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
- 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
- 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
- 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
- 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
- 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
- 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
- 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
- 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
- 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
- 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
- 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
- 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
- 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
- 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
- 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
- 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
- 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
- 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
- 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
- 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
- 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
- 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
- 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
- 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
- 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
- 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
- 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
- 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
- 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
- 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
- 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
- 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
- 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
- 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
- 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
- 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
- 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
- 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
- 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
- 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
- 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
- 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
- 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
- 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
- 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
- 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
- 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
- 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
- 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
- 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
- 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
- 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
- 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
- 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
- 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
- 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
- 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
- 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
- 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
- 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
-};
-static u8 Te4[256] = {
- 0x63U, 0x7cU, 0x77U, 0x7bU,
- 0xf2U, 0x6bU, 0x6fU, 0xc5U,
- 0x30U, 0x01U, 0x67U, 0x2bU,
- 0xfeU, 0xd7U, 0xabU, 0x76U,
- 0xcaU, 0x82U, 0xc9U, 0x7dU,
- 0xfaU, 0x59U, 0x47U, 0xf0U,
- 0xadU, 0xd4U, 0xa2U, 0xafU,
- 0x9cU, 0xa4U, 0x72U, 0xc0U,
- 0xb7U, 0xfdU, 0x93U, 0x26U,
- 0x36U, 0x3fU, 0xf7U, 0xccU,
- 0x34U, 0xa5U, 0xe5U, 0xf1U,
- 0x71U, 0xd8U, 0x31U, 0x15U,
- 0x04U, 0xc7U, 0x23U, 0xc3U,
- 0x18U, 0x96U, 0x05U, 0x9aU,
- 0x07U, 0x12U, 0x80U, 0xe2U,
- 0xebU, 0x27U, 0xb2U, 0x75U,
- 0x09U, 0x83U, 0x2cU, 0x1aU,
- 0x1bU, 0x6eU, 0x5aU, 0xa0U,
- 0x52U, 0x3bU, 0xd6U, 0xb3U,
- 0x29U, 0xe3U, 0x2fU, 0x84U,
- 0x53U, 0xd1U, 0x00U, 0xedU,
- 0x20U, 0xfcU, 0xb1U, 0x5bU,
- 0x6aU, 0xcbU, 0xbeU, 0x39U,
- 0x4aU, 0x4cU, 0x58U, 0xcfU,
- 0xd0U, 0xefU, 0xaaU, 0xfbU,
- 0x43U, 0x4dU, 0x33U, 0x85U,
- 0x45U, 0xf9U, 0x02U, 0x7fU,
- 0x50U, 0x3cU, 0x9fU, 0xa8U,
- 0x51U, 0xa3U, 0x40U, 0x8fU,
- 0x92U, 0x9dU, 0x38U, 0xf5U,
- 0xbcU, 0xb6U, 0xdaU, 0x21U,
- 0x10U, 0xffU, 0xf3U, 0xd2U,
- 0xcdU, 0x0cU, 0x13U, 0xecU,
- 0x5fU, 0x97U, 0x44U, 0x17U,
- 0xc4U, 0xa7U, 0x7eU, 0x3dU,
- 0x64U, 0x5dU, 0x19U, 0x73U,
- 0x60U, 0x81U, 0x4fU, 0xdcU,
- 0x22U, 0x2aU, 0x90U, 0x88U,
- 0x46U, 0xeeU, 0xb8U, 0x14U,
- 0xdeU, 0x5eU, 0x0bU, 0xdbU,
- 0xe0U, 0x32U, 0x3aU, 0x0aU,
- 0x49U, 0x06U, 0x24U, 0x5cU,
- 0xc2U, 0xd3U, 0xacU, 0x62U,
- 0x91U, 0x95U, 0xe4U, 0x79U,
- 0xe7U, 0xc8U, 0x37U, 0x6dU,
- 0x8dU, 0xd5U, 0x4eU, 0xa9U,
- 0x6cU, 0x56U, 0xf4U, 0xeaU,
- 0x65U, 0x7aU, 0xaeU, 0x08U,
- 0xbaU, 0x78U, 0x25U, 0x2eU,
- 0x1cU, 0xa6U, 0xb4U, 0xc6U,
- 0xe8U, 0xddU, 0x74U, 0x1fU,
- 0x4bU, 0xbdU, 0x8bU, 0x8aU,
- 0x70U, 0x3eU, 0xb5U, 0x66U,
- 0x48U, 0x03U, 0xf6U, 0x0eU,
- 0x61U, 0x35U, 0x57U, 0xb9U,
- 0x86U, 0xc1U, 0x1dU, 0x9eU,
- 0xe1U, 0xf8U, 0x98U, 0x11U,
- 0x69U, 0xd9U, 0x8eU, 0x94U,
- 0x9bU, 0x1eU, 0x87U, 0xe9U,
- 0xceU, 0x55U, 0x28U, 0xdfU,
- 0x8cU, 0xa1U, 0x89U, 0x0dU,
- 0xbfU, 0xe6U, 0x42U, 0x68U,
- 0x41U, 0x99U, 0x2dU, 0x0fU,
- 0xb0U, 0x54U, 0xbbU, 0x16U,
-};
-static u32 Td0[256] = {
- 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
- 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
- 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
- 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
- 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
- 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
- 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
- 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
- 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
- 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
- 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
- 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
- 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
- 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
- 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
- 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
- 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
- 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
- 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
- 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
- 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
- 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
- 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
- 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
- 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
- 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
- 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
- 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
- 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
- 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
- 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
- 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
- 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
- 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
- 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
- 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
- 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
- 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
- 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
- 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
- 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
- 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
- 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
- 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
- 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
- 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
- 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
- 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
- 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
- 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
- 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
- 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
- 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
- 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
- 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
- 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
- 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
- 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
- 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
- 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
- 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
- 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
- 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
- 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
-};
-static u32 Td1[256] = {
- 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
- 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
- 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
- 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
- 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
- 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
- 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
- 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
- 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
- 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
- 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
- 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
- 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
- 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
- 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
- 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
- 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
- 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
- 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
- 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
- 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
- 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
- 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
- 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
- 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
- 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
- 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
- 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
- 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
- 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
- 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
- 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
- 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
- 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
- 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
- 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
- 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
- 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
- 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
- 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
- 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
- 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
- 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
- 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
- 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
- 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
- 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
- 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
- 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
- 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
- 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
- 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
- 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
- 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
- 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
- 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
- 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
- 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
- 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
- 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
- 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
- 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
- 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
- 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
-};
-static u32 Td2[256] = {
- 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
- 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
- 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
- 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
- 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
- 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
- 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
- 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
- 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
- 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
- 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
- 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
- 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
- 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
- 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
- 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
- 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
- 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
- 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
- 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
-
- 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
- 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
- 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
- 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
- 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
- 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
- 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
- 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
- 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
- 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
- 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
- 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
- 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
- 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
- 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
- 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
- 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
- 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
- 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
- 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
- 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
- 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
- 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
- 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
- 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
- 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
- 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
- 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
- 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
- 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
- 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
- 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
- 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
- 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
- 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
- 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
- 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
- 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
- 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
- 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
- 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
- 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
- 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
- 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
-};
-static u32 Td3[256] = {
- 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
- 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
- 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
- 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
- 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
- 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
- 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
- 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
- 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
- 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
- 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
- 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
- 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
- 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
- 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
- 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
- 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
- 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
- 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
- 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
- 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
- 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
- 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
- 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
- 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
- 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
- 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
- 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
- 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
- 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
- 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
- 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
- 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
- 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
- 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
- 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
- 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
- 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
- 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
- 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
- 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
- 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
- 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
- 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
- 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
- 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
- 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
- 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
- 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
- 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
- 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
- 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
- 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
- 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
- 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
- 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
- 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
- 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
- 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
- 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
- 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
- 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
- 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
- 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
-};
-static u8 Td4[256] = {
- 0x52U, 0x09U, 0x6aU, 0xd5U,
- 0x30U, 0x36U, 0xa5U, 0x38U,
- 0xbfU, 0x40U, 0xa3U, 0x9eU,
- 0x81U, 0xf3U, 0xd7U, 0xfbU,
- 0x7cU, 0xe3U, 0x39U, 0x82U,
- 0x9bU, 0x2fU, 0xffU, 0x87U,
- 0x34U, 0x8eU, 0x43U, 0x44U,
- 0xc4U, 0xdeU, 0xe9U, 0xcbU,
- 0x54U, 0x7bU, 0x94U, 0x32U,
- 0xa6U, 0xc2U, 0x23U, 0x3dU,
- 0xeeU, 0x4cU, 0x95U, 0x0bU,
- 0x42U, 0xfaU, 0xc3U, 0x4eU,
- 0x08U, 0x2eU, 0xa1U, 0x66U,
- 0x28U, 0xd9U, 0x24U, 0xb2U,
- 0x76U, 0x5bU, 0xa2U, 0x49U,
- 0x6dU, 0x8bU, 0xd1U, 0x25U,
- 0x72U, 0xf8U, 0xf6U, 0x64U,
- 0x86U, 0x68U, 0x98U, 0x16U,
- 0xd4U, 0xa4U, 0x5cU, 0xccU,
- 0x5dU, 0x65U, 0xb6U, 0x92U,
- 0x6cU, 0x70U, 0x48U, 0x50U,
- 0xfdU, 0xedU, 0xb9U, 0xdaU,
- 0x5eU, 0x15U, 0x46U, 0x57U,
- 0xa7U, 0x8dU, 0x9dU, 0x84U,
- 0x90U, 0xd8U, 0xabU, 0x00U,
- 0x8cU, 0xbcU, 0xd3U, 0x0aU,
- 0xf7U, 0xe4U, 0x58U, 0x05U,
- 0xb8U, 0xb3U, 0x45U, 0x06U,
- 0xd0U, 0x2cU, 0x1eU, 0x8fU,
- 0xcaU, 0x3fU, 0x0fU, 0x02U,
- 0xc1U, 0xafU, 0xbdU, 0x03U,
- 0x01U, 0x13U, 0x8aU, 0x6bU,
- 0x3aU, 0x91U, 0x11U, 0x41U,
- 0x4fU, 0x67U, 0xdcU, 0xeaU,
- 0x97U, 0xf2U, 0xcfU, 0xceU,
- 0xf0U, 0xb4U, 0xe6U, 0x73U,
- 0x96U, 0xacU, 0x74U, 0x22U,
- 0xe7U, 0xadU, 0x35U, 0x85U,
- 0xe2U, 0xf9U, 0x37U, 0xe8U,
- 0x1cU, 0x75U, 0xdfU, 0x6eU,
- 0x47U, 0xf1U, 0x1aU, 0x71U,
- 0x1dU, 0x29U, 0xc5U, 0x89U,
- 0x6fU, 0xb7U, 0x62U, 0x0eU,
- 0xaaU, 0x18U, 0xbeU, 0x1bU,
- 0xfcU, 0x56U, 0x3eU, 0x4bU,
- 0xc6U, 0xd2U, 0x79U, 0x20U,
- 0x9aU, 0xdbU, 0xc0U, 0xfeU,
- 0x78U, 0xcdU, 0x5aU, 0xf4U,
- 0x1fU, 0xddU, 0xa8U, 0x33U,
- 0x88U, 0x07U, 0xc7U, 0x31U,
- 0xb1U, 0x12U, 0x10U, 0x59U,
- 0x27U, 0x80U, 0xecU, 0x5fU,
- 0x60U, 0x51U, 0x7fU, 0xa9U,
- 0x19U, 0xb5U, 0x4aU, 0x0dU,
- 0x2dU, 0xe5U, 0x7aU, 0x9fU,
- 0x93U, 0xc9U, 0x9cU, 0xefU,
- 0xa0U, 0xe0U, 0x3bU, 0x4dU,
- 0xaeU, 0x2aU, 0xf5U, 0xb0U,
- 0xc8U, 0xebU, 0xbbU, 0x3cU,
- 0x83U, 0x53U, 0x99U, 0x61U,
- 0x17U, 0x2bU, 0x04U, 0x7eU,
- 0xbaU, 0x77U, 0xd6U, 0x26U,
- 0xe1U, 0x69U, 0x14U, 0x63U,
- 0x55U, 0x21U, 0x0cU, 0x7dU,
-};
-static u32 rcon[] = {
- 0x01000000, 0x02000000, 0x04000000, 0x08000000,
- 0x10000000, 0x20000000, 0x40000000, 0x80000000,
- 0x1B000000, 0x36000000,
- /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
-};
-
-/*
- * Expand the cipher key into the encryption key schedule.
- *
- * @return the number of rounds for the given cipher key size.
- */
-static int
-setupEnc(ulong rk[/*4*(Nr + 1)*/], uchar key[], int nkey)
-{
- int i = 0;
- u32 temp;
-
- rk[0] = GETU32(key );
- rk[1] = GETU32(key + 4);
- rk[2] = GETU32(key + 8);
- rk[3] = GETU32(key + 12);
- if (nkey == 16) {
- for (;;) {
- temp = rk[3];
- rk[4] = rk[0] ^
- (Te4[(temp >> 16) & 0xff] << 24) ^
- (Te4[(temp >> 8) & 0xff] << 16) ^
- (Te4[(temp ) & 0xff] << 8) ^
- (Te4[(temp >> 24) ] ) ^
- rcon[i];
- rk[5] = rk[1] ^ rk[4];
- rk[6] = rk[2] ^ rk[5];
- rk[7] = rk[3] ^ rk[6];
- if (++i == 10) {
- return 10;
- }
- rk += 4;
- }
- }
- rk[4] = GETU32(key + 16);
- rk[5] = GETU32(key + 20);
- if (nkey == 24) {
- for (;;) {
- temp = rk[ 5];
- rk[ 6] = rk[ 0] ^
- (Te4[(temp >> 16) & 0xff] << 24) ^
- (Te4[(temp >> 8) & 0xff] << 16) ^
- (Te4[(temp ) & 0xff] << 8) ^
- (Te4[(temp >> 24) ] ) ^
- rcon[i];
- rk[ 7] = rk[ 1] ^ rk[ 6];
- rk[ 8] = rk[ 2] ^ rk[ 7];
- rk[ 9] = rk[ 3] ^ rk[ 8];
- if (++i == 8) {
- return 12;
- }
- rk[10] = rk[ 4] ^ rk[ 9];
- rk[11] = rk[ 5] ^ rk[10];
- rk += 6;
- }
- }
- rk[6] = GETU32(key + 24);
- rk[7] = GETU32(key + 28);
- if (nkey == 32) {
- for (;;) {
- temp = rk[ 7];
- rk[ 8] = rk[ 0] ^
- (Te4[(temp >> 16) & 0xff] << 24) ^
- (Te4[(temp >> 8) & 0xff] << 16) ^
- (Te4[(temp ) & 0xff] << 8) ^
- (Te4[(temp >> 24) ] ) ^
- rcon[i];
- rk[ 9] = rk[ 1] ^ rk[ 8];
- rk[10] = rk[ 2] ^ rk[ 9];
- rk[11] = rk[ 3] ^ rk[10];
- if (++i == 7) {
- return 14;
- }
- temp = rk[11];
- rk[12] = rk[ 4] ^
- (Te4[(temp >> 24) ] << 24) ^
- (Te4[(temp >> 16) & 0xff] << 16) ^
- (Te4[(temp >> 8) & 0xff] << 8) ^
- (Te4[(temp ) & 0xff] );
- rk[13] = rk[ 5] ^ rk[12];
- rk[14] = rk[ 6] ^ rk[13];
- rk[15] = rk[ 7] ^ rk[14];
- rk += 8;
- }
- }
- return 0;
-}
-
-/*
- * Expand the cipher key into the encryption and decryption key schedules.
- *
- * @return the number of rounds for the given cipher key size.
- */
-static int
-AESsetup(ulong erk[/* 4*(Nr + 1) */], ulong drk[/* 4*(Nr + 1) */], uchar key[], int nkey)
-{
- int Nr, i;
-
- /* expand the cipher key: */
- Nr = setupEnc(erk, key, nkey);
-
- /*
- * invert the order of the round keys and apply the inverse MixColumn
- * transform to all round keys but the first and the last
- */
- drk[0 ] = erk[4*Nr ];
- drk[1 ] = erk[4*Nr + 1];
- drk[2 ] = erk[4*Nr + 2];
- drk[3 ] = erk[4*Nr + 3];
- drk[4*Nr ] = erk[0 ];
- drk[4*Nr + 1] = erk[1 ];
- drk[4*Nr + 2] = erk[2 ];
- drk[4*Nr + 3] = erk[3 ];
- erk += 4 * Nr;
- for (i = 1; i < Nr; i++) {
- drk += 4;
- erk -= 4;
- drk[0] =
- Td0[Te4[(erk[0] >> 24) ]] ^
- Td1[Te4[(erk[0] >> 16) & 0xff]] ^
- Td2[Te4[(erk[0] >> 8) & 0xff]] ^
- Td3[Te4[(erk[0] ) & 0xff]];
- drk[1] =
- Td0[Te4[(erk[1] >> 24) ]] ^
- Td1[Te4[(erk[1] >> 16) & 0xff]] ^
- Td2[Te4[(erk[1] >> 8) & 0xff]] ^
- Td3[Te4[(erk[1] ) & 0xff]];
- drk[2] =
- Td0[Te4[(erk[2] >> 24) ]] ^
- Td1[Te4[(erk[2] >> 16) & 0xff]] ^
- Td2[Te4[(erk[2] >> 8) & 0xff]] ^
- Td3[Te4[(erk[2] ) & 0xff]];
- drk[3] =
- Td0[Te4[(erk[3] >> 24) ]] ^
- Td1[Te4[(erk[3] >> 16) & 0xff]] ^
- Td2[Te4[(erk[3] >> 8) & 0xff]] ^
- Td3[Te4[(erk[3] ) & 0xff]];
- }
- return Nr;
-}
-
-/* using round keys in rk, perform Nr rounds of encrypting pt into ct */
-static void
-AESencrypt(ulong rk[/* 4*(Nr + 1) */], int Nr, uchar pt[16], uchar ct[16])
-{
- ulong s0, s1, s2, s3, t0, t1, t2, t3;
-#ifndef FULL_UNROLL
- int r;
-#endif /* ?FULL_UNROLL */
-
- /*
- * map byte array block to cipher state
- * and add initial round key:
- */
- s0 = GETU32(pt ) ^ rk[0];
- s1 = GETU32(pt + 4) ^ rk[1];
- s2 = GETU32(pt + 8) ^ rk[2];
- s3 = GETU32(pt + 12) ^ rk[3];
-#ifdef FULL_UNROLL
- /* round 1: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
- /* round 2: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
- /* round 3: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
- /* round 4: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
- /* round 5: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
- /* round 6: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
- /* round 7: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
- /* round 8: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
- /* round 9: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
- if (Nr > 10) {
- /* round 10: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
- /* round 11: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
- if (Nr > 12) {
- /* round 12: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
- /* round 13: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
- }
- }
- rk += Nr << 2;
-#else /* !FULL_UNROLL */
- /*
- * Nr - 1 full rounds:
- */
- r = Nr >> 1;
- for (;;) {
- t0 =
- Te0[(s0 >> 24) ] ^
- Te1[(s1 >> 16) & 0xff] ^
- Te2[(s2 >> 8) & 0xff] ^
- Te3[(s3 ) & 0xff] ^
- rk[4];
- t1 =
- Te0[(s1 >> 24) ] ^
- Te1[(s2 >> 16) & 0xff] ^
- Te2[(s3 >> 8) & 0xff] ^
- Te3[(s0 ) & 0xff] ^
- rk[5];
- t2 =
- Te0[(s2 >> 24) ] ^
- Te1[(s3 >> 16) & 0xff] ^
- Te2[(s0 >> 8) & 0xff] ^
- Te3[(s1 ) & 0xff] ^
- rk[6];
- t3 =
- Te0[(s3 >> 24) ] ^
- Te1[(s0 >> 16) & 0xff] ^
- Te2[(s1 >> 8) & 0xff] ^
- Te3[(s2 ) & 0xff] ^
- rk[7];
-
- rk += 8;
- if (--r == 0)
- break;
-
- s0 =
- Te0[(t0 >> 24) ] ^
- Te1[(t1 >> 16) & 0xff] ^
- Te2[(t2 >> 8) & 0xff] ^
- Te3[(t3 ) & 0xff] ^
- rk[0];
- s1 =
- Te0[(t1 >> 24) ] ^
- Te1[(t2 >> 16) & 0xff] ^
- Te2[(t3 >> 8) & 0xff] ^
- Te3[(t0 ) & 0xff] ^
- rk[1];
- s2 =
- Te0[(t2 >> 24) ] ^
- Te1[(t3 >> 16) & 0xff] ^
- Te2[(t0 >> 8) & 0xff] ^
- Te3[(t1 ) & 0xff] ^
- rk[2];
- s3 =
- Te0[(t3 >> 24) ] ^
- Te1[(t0 >> 16) & 0xff] ^
- Te2[(t1 >> 8) & 0xff] ^
- Te3[(t2 ) & 0xff] ^
- rk[3];
- }
-#endif /* ?FULL_UNROLL */
- /*
- * apply last round and
- * map cipher state to byte array block:
- */
- s0 =
- (Te4[(t0 >> 24) ] << 24) ^
- (Te4[(t1 >> 16) & 0xff] << 16) ^
- (Te4[(t2 >> 8) & 0xff] << 8) ^
- (Te4[(t3 ) & 0xff] ) ^
- rk[0];
- PUTU32(ct , s0);
- s1 =
- (Te4[(t1 >> 24) ] << 24) ^
- (Te4[(t2 >> 16) & 0xff] << 16) ^
- (Te4[(t3 >> 8) & 0xff] << 8) ^
- (Te4[(t0 ) & 0xff] ) ^
- rk[1];
- PUTU32(ct + 4, s1);
- s2 =
- (Te4[(t2 >> 24) ] << 24) ^
- (Te4[(t3 >> 16) & 0xff] << 16) ^
- (Te4[(t0 >> 8) & 0xff] << 8) ^
- (Te4[(t1 ) & 0xff] ) ^
- rk[2];
- PUTU32(ct + 8, s2);
- s3 =
- (Te4[(t3 >> 24) ] << 24) ^
- (Te4[(t0 >> 16) & 0xff] << 16) ^
- (Te4[(t1 >> 8) & 0xff] << 8) ^
- (Te4[(t2 ) & 0xff] ) ^
- rk[3];
- PUTU32(ct + 12, s3);
-}
-
-static void
-AESdecrypt(ulong rk[/* 4*(Nr + 1) */], int Nr, uchar ct[16], uchar pt[16])
-{
- ulong s0, s1, s2, s3, t0, t1, t2, t3;
-#ifndef FULL_UNROLL
- int r;
-#endif /* ?FULL_UNROLL */
-
- /*
- * map byte array block to cipher state
- * and add initial round key:
- */
- s0 = GETU32(ct ) ^ rk[0];
- s1 = GETU32(ct + 4) ^ rk[1];
- s2 = GETU32(ct + 8) ^ rk[2];
- s3 = GETU32(ct + 12) ^ rk[3];
-#ifdef FULL_UNROLL
- /* round 1: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
- /* round 2: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
- /* round 3: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
- /* round 4: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
- /* round 5: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
- /* round 6: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
- /* round 7: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
- /* round 8: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
- /* round 9: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
- if (Nr > 10) {
- /* round 10: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
- /* round 11: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
- if (Nr > 12) {
- /* round 12: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
- /* round 13: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
- }
- }
- rk += Nr << 2;
-#else /* !FULL_UNROLL */
- /*
- * Nr - 1 full rounds:
- */
- r = Nr >> 1;
- for (;;) {
- t0 =
- Td0[(s0 >> 24) ] ^
- Td1[(s3 >> 16) & 0xff] ^
- Td2[(s2 >> 8) & 0xff] ^
- Td3[(s1 ) & 0xff] ^
- rk[4];
- t1 =
- Td0[(s1 >> 24) ] ^
- Td1[(s0 >> 16) & 0xff] ^
- Td2[(s3 >> 8) & 0xff] ^
- Td3[(s2 ) & 0xff] ^
- rk[5];
- t2 =
- Td0[(s2 >> 24) ] ^
- Td1[(s1 >> 16) & 0xff] ^
- Td2[(s0 >> 8) & 0xff] ^
- Td3[(s3 ) & 0xff] ^
- rk[6];
- t3 =
- Td0[(s3 >> 24) ] ^
- Td1[(s2 >> 16) & 0xff] ^
- Td2[(s1 >> 8) & 0xff] ^
- Td3[(s0 ) & 0xff] ^
- rk[7];
-
- rk += 8;
- if (--r == 0)
- break;
-
- s0 =
- Td0[(t0 >> 24) ] ^
- Td1[(t3 >> 16) & 0xff] ^
- Td2[(t2 >> 8) & 0xff] ^
- Td3[(t1 ) & 0xff] ^
- rk[0];
- s1 =
- Td0[(t1 >> 24) ] ^
- Td1[(t0 >> 16) & 0xff] ^
- Td2[(t3 >> 8) & 0xff] ^
- Td3[(t2 ) & 0xff] ^
- rk[1];
- s2 =
- Td0[(t2 >> 24) ] ^
- Td1[(t1 >> 16) & 0xff] ^
- Td2[(t0 >> 8) & 0xff] ^
- Td3[(t3 ) & 0xff] ^
- rk[2];
- s3 =
- Td0[(t3 >> 24) ] ^
- Td1[(t2 >> 16) & 0xff] ^
- Td2[(t1 >> 8) & 0xff] ^
- Td3[(t0 ) & 0xff] ^
- rk[3];
- }
-#endif /* ?FULL_UNROLL */
- /*
- * apply last round and
- * map cipher state to byte array block:
- */
- s0 =
- (Td4[(t0 >> 24) ] << 24) ^
- (Td4[(t3 >> 16) & 0xff] << 16) ^
- (Td4[(t2 >> 8) & 0xff] << 8) ^
- (Td4[(t1 ) & 0xff] ) ^
- rk[0];
- PUTU32(pt , s0);
- s1 =
- (Td4[(t1 >> 24) ] << 24) ^
- (Td4[(t0 >> 16) & 0xff] << 16) ^
- (Td4[(t3 >> 8) & 0xff] << 8) ^
- (Td4[(t2 ) & 0xff] ) ^
- rk[1];
- PUTU32(pt + 4, s1);
- s2 =
- (Td4[(t2 >> 24) ] << 24) ^
- (Td4[(t1 >> 16) & 0xff] << 16) ^
- (Td4[(t0 >> 8) & 0xff] << 8) ^
- (Td4[(t3 ) & 0xff] ) ^
- rk[2];
- PUTU32(pt + 8, s2);
- s3 =
- (Td4[(t3 >> 24) ] << 24) ^
- (Td4[(t2 >> 16) & 0xff] << 16) ^
- (Td4[(t1 >> 8) & 0xff] << 8) ^
- (Td4[(t0 ) & 0xff] ) ^
- rk[3];
- PUTU32(pt + 12, s3);
-}
-
-void (*aes_encrypt)(ulong rk[], int Nr, uchar pt[16], uchar ct[16]) = AESencrypt;
-void (*aes_decrypt)(ulong rk[], int Nr, uchar ct[16], uchar pt[16]) = AESdecrypt;
-
-void
-setupAESstate(AESstate *s, uchar key[], int nkey, uchar *ivec)
-{
- static int (*aes_setup)(ulong erk[/* 4*(Nr + 1) */], ulong drk[/* 4*(Nr + 1) */], uchar key[], int nkey);
-
- if(aes_setup == nil){
- extern void *aesni_init(void);
- if((aes_setup = aesni_init()) == nil)
- aes_setup = AESsetup;
- }
- memset(s, 0, sizeof(*s));
- if(nkey > AESmaxkey)
- nkey = AESmaxkey;
- memmove(s->key, key, nkey);
- s->keybytes = nkey;
- s->ekey = s->storage+16 - ((s->storage - (uchar*)0) & 15);
- s->dkey = (uchar*)s->ekey + 16*(AESmaxrounds+1);
- s->rounds = (*aes_setup)(s->ekey, s->dkey, s->key, nkey);
- if(ivec != nil)
- memmove(s->ivec, ivec, AESbsize);
- if(s->rounds != 0)
- s->setup = 0xcafebabe;
-}
--- a/libsec/aesCBC.c
+++ /dev/null
@@ -1,60 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-/*
- * Define by analogy with desCBCencrypt; AES modes are not standardized yet.
- * Because of the way that non-multiple-of-16 buffers are handled,
- * the decryptor must be fed buffers of the same size as the encryptor.
- */
-void
-aesCBCencrypt(uchar *p, int len, AESstate *s)
-{
- uchar *p2, *ip, *eip;
- uchar q[AESbsize];
-
- for(; len >= AESbsize; len -= AESbsize){
- p2 = p;
- ip = s->ivec;
- for(eip = ip+AESbsize; ip < eip; )
- *p2++ ^= *ip++;
- aes_encrypt(s->ekey, s->rounds, p, q);
- memmove(s->ivec, q, AESbsize);
- memmove(p, q, AESbsize);
- p += AESbsize;
- }
-
- if(len > 0){
- ip = s->ivec;
- aes_encrypt(s->ekey, s->rounds, ip, q);
- memmove(s->ivec, q, AESbsize);
- for(eip = ip+len; ip < eip; )
- *p++ ^= *ip++;
- }
-}
-
-void
-aesCBCdecrypt(uchar *p, int len, AESstate *s)
-{
- uchar *ip, *eip, *tp;
- uchar tmp[AESbsize], q[AESbsize];
-
- for(; len >= AESbsize; len -= AESbsize){
- memmove(tmp, p, AESbsize);
- aes_decrypt(s->dkey, s->rounds, p, q);
- memmove(p, q, AESbsize);
- tp = tmp;
- ip = s->ivec;
- for(eip = ip+AESbsize; ip < eip; ){
- *p++ ^= *ip;
- *ip++ = *tp++;
- }
- }
-
- if(len > 0){
- ip = s->ivec;
- aes_encrypt(s->ekey, s->rounds, ip, q);
- memmove(s->ivec, q, AESbsize);
- for(eip = ip+len; ip < eip; )
- *p++ ^= *ip++;
- }
-}
--- a/libsec/aesCFB.c
+++ /dev/null
@@ -1,50 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-typedef ulong u32;
-
-void
-aesCFBencrypt(uchar *p, int len, AESstate *s)
-{
- u32 a, o = s->offset;
-
- while(len > 0){
- if(o % 16){
- Odd:
- a = (s->ivec[o++ % 16] ^= *p), *p++ = a, len--;
- continue;
- }
- aes_encrypt(s->ekey, s->rounds, s->ivec, s->ivec);
- if(len < 16 || ((p-(uchar*)0) & 3) != 0)
- goto Odd;
- ((u32*)p)[0] = (((u32*)s->ivec)[0] ^= ((u32*)p)[0]);
- ((u32*)p)[1] = (((u32*)s->ivec)[1] ^= ((u32*)p)[1]);
- ((u32*)p)[2] = (((u32*)s->ivec)[2] ^= ((u32*)p)[2]);
- ((u32*)p)[3] = (((u32*)s->ivec)[3] ^= ((u32*)p)[3]);
- o += 16, p += 16, len -= 16;
- }
- s->offset = o;
-}
-
-void
-aesCFBdecrypt(uchar *p, int len, AESstate *s)
-{
- u32 a, o = s->offset;
-
- while(len > 0){
- if(o % 16){
- Odd:
- a = *p, *p++ ^= s->ivec[o % 16], s->ivec[o++ % 16] = a, len--;
- continue;
- }
- aes_encrypt(s->ekey, s->rounds, s->ivec, s->ivec);
- if(len < 16 || ((p-(uchar*)0) & 3) != 0)
- goto Odd;
- a = ((u32*)p)[0], ((u32*)p)[0] ^= ((u32*)s->ivec)[0], ((u32*)s->ivec)[0] = a;
- a = ((u32*)p)[1], ((u32*)p)[1] ^= ((u32*)s->ivec)[1], ((u32*)s->ivec)[1] = a;
- a = ((u32*)p)[2], ((u32*)p)[2] ^= ((u32*)s->ivec)[2], ((u32*)s->ivec)[2] = a;
- a = ((u32*)p)[3], ((u32*)p)[3] ^= ((u32*)s->ivec)[3], ((u32*)s->ivec)[3] = a;
- o += 16, p += 16, len -= 16;
- }
- s->offset = o;
-}
--- a/libsec/aesOFB.c
+++ /dev/null
@@ -1,28 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-typedef ulong u32;
-
-void
-aesOFBencrypt(uchar *p, int len, AESstate *s)
-{
- u32 o = s->offset;
-
- while(len > 0){
- if(o % 16){
- Odd:
- *p++ ^= s->ivec[o++ % 16], len--;
- continue;
- }
- aes_encrypt(s->ekey, s->rounds, s->ivec, s->ivec);
- if(len < 16 || ((p-(uchar*)0) & 3) != 0)
- goto Odd;
- ((u32*)p)[0] ^= ((u32*)s->ivec)[0];
- ((u32*)p)[1] ^= ((u32*)s->ivec)[1];
- ((u32*)p)[2] ^= ((u32*)s->ivec)[2];
- ((u32*)p)[3] ^= ((u32*)s->ivec)[3];
- o += 16, p += 16, len -= 16;
- }
- s->offset = o;
-}
-
--- a/libsec/aes_gcm.c
+++ /dev/null
@@ -1,199 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-static void
-load128(uchar b[16], ulong W[4])
-{
- W[0] = (ulong)b[15] | (ulong)b[14]<<8 | (ulong)b[13]<<16 | (ulong)b[12]<<24;
- W[1] = (ulong)b[11] | (ulong)b[10]<<8 | (ulong)b[ 9]<<16 | (ulong)b[ 8]<<24;
- W[2] = (ulong)b[ 7] | (ulong)b[ 6]<<8 | (ulong)b[ 5]<<16 | (ulong)b[ 4]<<24;
- W[3] = (ulong)b[ 3] | (ulong)b[ 2]<<8 | (ulong)b[ 1]<<16 | (ulong)b[ 0]<<24;
-}
-
-static void
-store128(ulong W[4], uchar b[16])
-{
- b[15] = W[0], b[14] = W[0]>>8, b[13] = W[0]>>16, b[12] = W[0]>>24;
- b[11] = W[1], b[10] = W[1]>>8, b[ 9] = W[1]>>16, b[ 8] = W[1]>>24;
- b[ 7] = W[2], b[ 6] = W[2]>>8, b[ 5] = W[2]>>16, b[ 4] = W[2]>>24;
- b[ 3] = W[3], b[ 2] = W[3]>>8, b[ 1] = W[3]>>16, b[ 0] = W[3]>>24;
-}
-
-static void
-gfmul(ulong X[4], ulong Y[4], ulong Z[4])
-{
- long m, i;
-
- Z[0] = Z[1] = Z[2] = Z[3] = 0;
- for(i=127; i>=0; i--){
- m = ((long)Y[i>>5] << (31-(i&31))) >> 31;
- Z[0] ^= X[0] & m;
- Z[1] ^= X[1] & m;
- Z[2] ^= X[2] & m;
- Z[3] ^= X[3] & m;
- m = ((long)X[0]<<31) >> 31;
- X[0] = X[0]>>1 | X[1]<<31;
- X[1] = X[1]>>1 | X[2]<<31;
- X[2] = X[2]>>1 | X[3]<<31;
- X[3] = X[3]>>1 ^ (0xE1000000 & m);
- }
-}
-
-static void
-prepareM(ulong H[4], ulong M[16][256][4])
-{
- ulong X[4], i, j;
-
- for(i=0; i<16; i++){
- for(j=0; j<256; j++){
- X[0] = X[1] = X[2] = X[3] = 0;
- X[i>>2] = j<<((i&3)<<3);
- gfmul(X, H, M[i][j]);
- }
- }
-}
-
-static void
-ghash1(AESGCMstate *s, ulong X[4], ulong Y[4])
-{
- ulong *Xi, i;
-
- X[0] ^= Y[0], X[1] ^= Y[1], X[2] ^= Y[2], X[3] ^= Y[3];
- if(0){
- gfmul(X, s->H, Y);
- return;
- }
-
- Y[0] = Y[1] = Y[2] = Y[3] = 0;
- for(i=0; i<16; i++){
- Xi = s->M[i][(X[i>>2]>>((i&3)<<3))&0xFF];
- Y[0] ^= Xi[0];
- Y[1] ^= Xi[1];
- Y[2] ^= Xi[2];
- Y[3] ^= Xi[3];
- }
-}
-
-static void
-ghashn(AESGCMstate *s, uchar *dat, ulong len, ulong Y[4])
-{
- uchar tmp[16];
- ulong X[4];
-
- while(len >= 16){
- load128(dat, X);
- ghash1(s, X, Y);
- dat += 16, len -= 16;
- }
- if(len > 0){
- memmove(tmp, dat, len);
- memset(tmp+len, 0, 16-len);
- load128(tmp, X);
- ghash1(s, X, Y);
- }
-}
-
-static ulong
-aesxctr1(AESstate *s, uchar ctr[AESbsize], uchar *dat, ulong len)
-{
- uchar tmp[AESbsize];
- ulong i;
-
- aes_encrypt(s->ekey, s->rounds, ctr, tmp);
- if(len > AESbsize)
- len = AESbsize;
- for(i=0; i<len; i++)
- dat[i] ^= tmp[i];
- return len;
-}
-
-static void
-aesxctrn(AESstate *s, uchar *dat, ulong len)
-{
- uchar ctr[AESbsize];
- ulong i;
-
- memmove(ctr, s->ivec, AESbsize);
- while(len > 0){
- for(i=AESbsize-1; i>=AESbsize-4; i--)
- if(++ctr[i] != 0)
- break;
-
- if(aesxctr1(s, ctr, dat, len) < AESbsize)
- break;
- dat += AESbsize;
- len -= AESbsize;
- }
-}
-
-void
-aesgcm_setiv(AESGCMstate *s, uchar *iv, int ivlen)
-{
- if(ivlen == 96/8){
- memmove(s->a.ivec, iv, ivlen);
- memset(s->a.ivec+ivlen, 0, AESbsize-ivlen);
- s->a.ivec[AESbsize-1] = 1;
- } else {
- ulong L[4], Y[4] = {0};
-
- ghashn(s, iv, ivlen, Y);
- L[0] = ivlen << 3;
- L[1] = ivlen >> 29;
- L[2] = L[3] = 0;
- ghash1(s, L, Y);
- store128(Y, s->a.ivec);
- }
-}
-
-void
-setupAESGCMstate(AESGCMstate *s, uchar *key, int keylen, uchar *iv, int ivlen)
-{
- setupAESstate(&s->a, key, keylen, nil);
-
- memset(s->a.ivec, 0, AESbsize);
- aes_encrypt(s->a.ekey, s->a.rounds, s->a.ivec, s->a.ivec);
- load128(s->a.ivec, s->H);
- memset(s->a.ivec, 0, AESbsize);
- prepareM(s->H, s->M);
-
- if(iv != nil && ivlen > 0)
- aesgcm_setiv(s, iv, ivlen);
-}
-
-void
-aesgcm_encrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], AESGCMstate *s)
-{
- ulong L[4], Y[4] = {0};
-
- ghashn(s, aad, naad, Y);
- aesxctrn(&s->a, dat, ndat);
- ghashn(s, dat, ndat, Y);
- L[0] = ndat << 3;
- L[1] = ndat >> 29;
- L[2] = naad << 3;
- L[3] = naad >> 29;
- ghash1(s, L, Y);
- store128(Y, tag);
- aesxctr1(&s->a, s->a.ivec, tag, 16);
-}
-
-int
-aesgcm_decrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], AESGCMstate *s)
-{
- ulong L[4], Y[4] = {0};
- uchar tmp[16];
-
- ghashn(s, aad, naad, Y);
- ghashn(s, dat, ndat, Y);
- L[0] = ndat << 3;
- L[1] = ndat >> 29;
- L[2] = naad << 3;
- L[3] = naad >> 29;
- ghash1(s, L, Y);
- store128(Y, tmp);
- aesxctr1(&s->a, s->a.ivec, tmp, 16);
- if(tsmemcmp(tag, tmp, 16) != 0)
- return -1;
- aesxctrn(&s->a, dat, ndat);
- return 0;
-}
--- a/libsec/aes_xts.c
+++ /dev/null
@@ -1,83 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-/* little-endian data order */
-#define GET4(p) ((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24))
-#define PUT4(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24
-
-static void
-gf_mulx(uchar *x)
-{
- ulong t0, t1, t2, t3, t4;
-
- t0 = GET4(x);
- t1 = GET4(x+4);
- t2 = GET4(x+8);
- t3 = GET4(x+12);
-
- t4 = (t3 >> 31);
- t3 = (t3 << 1) | (t2 >> 31);
- t2 = (t2 << 1) | (t1 >> 31);
- t1 = (t1 << 1) | (t0 >> 31);
- t0 = (t0 << 1) ^ (t4*135);
-
- PUT4(x, t0);
- PUT4(x+4, t1);
- PUT4(x+8, t2);
- PUT4(x+12, t3);
-}
-
-static void
-xor128(uchar *o, uchar *i1, uchar *i2)
-{
- int i;
-
- for(i=0; i<16; i++)
- o[i] = i1[i] ^ i2[i];
-}
-
-static void
-setupT(AESstate *tweak, uvlong sectorNumber, uchar T[AESbsize])
-{
- PUT4(T+0, (ulong)sectorNumber), sectorNumber >>= 32;
- PUT4(T+4, (ulong)sectorNumber);
- PUT4(T+8, 0);
- PUT4(T+12, 0);
- aes_encrypt(tweak->ekey, tweak->rounds, T, T);
-}
-
-void
-aes_xts_encrypt(AESstate *tweak, AESstate *ecb,
- uvlong sectorNumber, uchar *input, uchar *output, ulong len)
-{
- uchar T[AESbsize], x[AESbsize];
-
- if(len % AESbsize)
- abort();
-
- setupT(tweak, sectorNumber, T);
- for (; len > 0; len -= AESbsize, input += AESbsize, output += AESbsize) {
- xor128(x, input, T);
- aes_encrypt(ecb->ekey, ecb->rounds, x, x);
- xor128(output, x, T);
- gf_mulx(T);
- }
-}
-
-void
-aes_xts_decrypt(AESstate *tweak, AESstate *ecb,
- uvlong sectorNumber, uchar *input, uchar *output, ulong len)
-{
- uchar T[AESbsize], x[AESbsize];
-
- if(len % AESbsize)
- abort();
-
- setupT(tweak, sectorNumber, T);
- for (; len > 0; len -= AESbsize, input += AESbsize, output += AESbsize) {
- xor128(x, input, T);
- aes_decrypt(ecb->dkey, ecb->rounds, x, x);
- xor128(output, x, T);
- gf_mulx(T);
- }
-}
--- a/libsec/aesni.c
+++ /dev/null
@@ -1,5 +1,0 @@
-void*
-aesni_init(void)
-{
- return 0;
-}
--- a/libsec/blowfish.c
+++ /dev/null
@@ -1,524 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-// Blowfish block cipher. See:
-// Lecture Notes in Computer Science 809
-// Fast Software Encryption
-// Cambridge Security Workshop, Cambridge, England (1993)
-
-static u32int sbox[1024];
-static u32int pbox[BFrounds+2];
-
-static void bfencrypt(u32int *, BFstate *);
-static void bfdecrypt(u32int *, BFstate *);
-
-/*
- * Endianess agnostic functions to convert a
- * block (8-byte buffer) to a u32int array and
- * viceversa.
- */
-
-static void
-buf2ints(uchar *p, u32int *b)
-{
- b[0] = p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3];
- b[1] = p[4]<<24 | p[5]<<16 | p[6]<<8 | p[7];
-}
-
-static void
-ints2buf(u32int *b, uchar *p)
-{
- u32int u;
-
- u = b[0];
- p[0] = u>>24;
- p[1] = u>>16;
- p[2] = u>>8;
- p[3] = u;
-
- u = b[1];
- p[4] = u>>24;
- p[5] = u>>16;
- p[6] = u>>8;
- p[7] = u;
-}
-
-void
-setupBFstate(BFstate *s, uchar key[], int keybytes, uchar *ivec)
-{
- int i, j;
- u32int n, buf[2];
-
- memset(s, 0, sizeof(*s));
- memset(buf, 0, sizeof buf);
-
- if (keybytes > sizeof(s->key))
- keybytes = sizeof(s->key);
-
- memmove(s->key, key, keybytes);
-
- if (ivec != nil)
- memmove(s->ivec, ivec, sizeof(s->ivec));
- else
- memset(s->ivec, 0, sizeof(s->ivec));
-
- memmove(s->pbox, pbox, sizeof(pbox));
- memmove(s->sbox, sbox, sizeof(sbox));
-
- if (keybytes > 4*(BFrounds + 2))
- keybytes = 4*(BFrounds + 2);
-
- for(i=j=0; i < BFrounds+2; i++) {
- n = key[j];
- j = (j+1) % keybytes;
-
- n <<= 8;
- n |= key[j];
- j = (j+1) % keybytes;
-
- n <<= 8;
- n |= key[j];
- j = (j+1) % keybytes;
-
- n <<= 8;
- n |= key[j];
- j = (j+1) % keybytes;
-
- s->pbox[i] ^= n;
- }
-
- for(i=0; i < BFrounds+2; i += 2) {
- bfencrypt(buf, s);
- s->pbox[i] = buf[0];
- s->pbox[i+1] = buf[1];
- }
-
- for(i=0; i < 1024; i += 2) {
- bfencrypt(buf, s);
- s->sbox[i] = buf[0];
- s->sbox[i+1] = buf[1];
- }
-
- s->setup = 0xcafebabe;
-}
-
-void
-bfCBCencrypt(uchar *buf, int n, BFstate *s)
-{
- int i;
- u32int bo[2], bi[2];
-
- assert((n & 7) == 0);
-
- buf2ints(s->ivec, bo);
- for(i=0; i < n; i += 8, buf += 8) {
- buf2ints(buf, bi);
-
- bi[0] ^= bo[0];
- bi[1] ^= bo[1];
-
- bfencrypt(bi, s);
-
- bo[0] = bi[0];
- bo[1] = bi[1];
-
- ints2buf(bi, buf);
- }
- ints2buf(bo, s->ivec);
- return;
-}
-
-void
-bfCBCdecrypt(uchar *buf, int n, BFstate *s)
-{
- int i;
- u32int bo[2], bi[2], xr[2];
-
- assert((n & 7) == 0);
-
- buf2ints(s->ivec, bo);
- for(i=0; i < n; i += 8, buf += 8) {
- buf2ints(buf, bi);
-
- xr[0] = bi[0];
- xr[1] = bi[1];
-
- bfdecrypt(bi, s);
-
- bo[0] ^= bi[0];
- bo[1] ^= bi[1];
-
- ints2buf(bo, buf);
-
- bo[0] = xr[0];
- bo[1] = xr[1];
- }
- ints2buf(bo, s->ivec);
- return;
-}
-
-void
-bfECBencrypt(uchar *buf, int n, BFstate *s)
-{
- int i;
- u32int b[2];
-
- for(i=0; i < n; i += 8, buf += 8) {
- buf2ints(buf, b);
- bfencrypt(b, s);
- ints2buf(b, buf);
- }
-
- return;
-}
-
-void
-bfECBdecrypt(uchar *buf, int n, BFstate *s)
-{
- int i;
- u32int b[2];
-
- for(i=0; i < n; i += 8, buf += 8) {
- buf2ints(buf, b);
- bfdecrypt(b, s);
- ints2buf(b, buf);
- }
-
- return;
-}
-
-static void
-bfencrypt(u32int *b, BFstate *s)
-{
- int i;
- u32int l, r;
- u32int *pb, *sb;
-
- l = b[0];
- r = b[1];
-
- pb = s->pbox;
- sb = s->sbox;
-
- l ^= pb[0];
-
- for(i=1; i<16; i += 2) {
- r ^= pb[i];
- r ^= ( (sb[ (uchar) (l>>24)] + sb[256 + ((uchar) (l>>16))]) ^
- sb[512 + ((uchar) (l>>8))]) + sb[768 +((uchar) l)];
-
- l ^= pb[i+1];
- l ^= ( (sb[ (uchar) (r>>24)] + sb[256 + ((uchar) (r>>16))]) ^
- sb[512 + ((uchar) (r>>8))]) + sb[768 +((uchar) r)];
- }
-
- r ^= pb[BFrounds+1];
-
- /* sic */
- b[0] = r;
- b[1] = l;
-
- return;
-}
-
-static void
-bfdecrypt(u32int *b, BFstate *s)
-{
- int i;
- u32int l, r;
- u32int *pb, *sb;
-
- l = b[0];
- r = b[1];
-
- pb = s->pbox;
- sb = s->sbox;
-
- l ^= pb[BFrounds+1];
-
- for(i=16; i > 0; i -= 2) {
- r ^= pb[i];
- r ^= ( (sb[ (uchar) (l>>24)] + sb[256 + ((uchar) (l>>16))]) ^
- sb[512 + ((uchar) (l>>8))]) + sb[768 +((uchar) l)];
-
- l ^= pb[i-1];
- l ^= ( (sb[ (uchar) (r>>24)] + sb[256 + ((uchar) (r>>16))]) ^
- sb[512 + ((uchar) (r>>8))]) + sb[768 +((uchar) r)];
- }
-
- r ^= pb[0];
-
- /* sic */
- b[0] = r;
- b[1] = l;
-
- return;
-}
-
-static u32int pbox[BFrounds+2] = {
- 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
- 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
- 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
- 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
- 0x9216d5d9, 0x8979fb1b
-};
-
-static u32int sbox[1024] = {
- 0xd1310ba6L, 0x98dfb5acL, 0x2ffd72dbL, 0xd01adfb7L,
- 0xb8e1afedL, 0x6a267e96L, 0xba7c9045L, 0xf12c7f99L,
- 0x24a19947L, 0xb3916cf7L, 0x0801f2e2L, 0x858efc16L,
- 0x636920d8L, 0x71574e69L, 0xa458fea3L, 0xf4933d7eL,
- 0x0d95748fL, 0x728eb658L, 0x718bcd58L, 0x82154aeeL,
- 0x7b54a41dL, 0xc25a59b5L, 0x9c30d539L, 0x2af26013L,
- 0xc5d1b023L, 0x286085f0L, 0xca417918L, 0xb8db38efL,
- 0x8e79dcb0L, 0x603a180eL, 0x6c9e0e8bL, 0xb01e8a3eL,
- 0xd71577c1L, 0xbd314b27L, 0x78af2fdaL, 0x55605c60L,
- 0xe65525f3L, 0xaa55ab94L, 0x57489862L, 0x63e81440L,
- 0x55ca396aL, 0x2aab10b6L, 0xb4cc5c34L, 0x1141e8ceL,
- 0xa15486afL, 0x7c72e993L, 0xb3ee1411L, 0x636fbc2aL,
- 0x2ba9c55dL, 0x741831f6L, 0xce5c3e16L, 0x9b87931eL,
- 0xafd6ba33L, 0x6c24cf5cL, 0x7a325381L, 0x28958677L,
- 0x3b8f4898L, 0x6b4bb9afL, 0xc4bfe81bL, 0x66282193L,
- 0x61d809ccL, 0xfb21a991L, 0x487cac60L, 0x5dec8032L,
- 0xef845d5dL, 0xe98575b1L, 0xdc262302L, 0xeb651b88L,
- 0x23893e81L, 0xd396acc5L, 0x0f6d6ff3L, 0x83f44239L,
- 0x2e0b4482L, 0xa4842004L, 0x69c8f04aL, 0x9e1f9b5eL,
- 0x21c66842L, 0xf6e96c9aL, 0x670c9c61L, 0xabd388f0L,
- 0x6a51a0d2L, 0xd8542f68L, 0x960fa728L, 0xab5133a3L,
- 0x6eef0b6cL, 0x137a3be4L, 0xba3bf050L, 0x7efb2a98L,
- 0xa1f1651dL, 0x39af0176L, 0x66ca593eL, 0x82430e88L,
- 0x8cee8619L, 0x456f9fb4L, 0x7d84a5c3L, 0x3b8b5ebeL,
- 0xe06f75d8L, 0x85c12073L, 0x401a449fL, 0x56c16aa6L,
- 0x4ed3aa62L, 0x363f7706L, 0x1bfedf72L, 0x429b023dL,
- 0x37d0d724L, 0xd00a1248L, 0xdb0fead3L, 0x49f1c09bL,
- 0x075372c9L, 0x80991b7bL, 0x25d479d8L, 0xf6e8def7L,
- 0xe3fe501aL, 0xb6794c3bL, 0x976ce0bdL, 0x04c006baL,
- 0xc1a94fb6L, 0x409f60c4L, 0x5e5c9ec2L, 0x196a2463L,
- 0x68fb6fafL, 0x3e6c53b5L, 0x1339b2ebL, 0x3b52ec6fL,
- 0x6dfc511fL, 0x9b30952cL, 0xcc814544L, 0xaf5ebd09L,
- 0xbee3d004L, 0xde334afdL, 0x660f2807L, 0x192e4bb3L,
- 0xc0cba857L, 0x45c8740fL, 0xd20b5f39L, 0xb9d3fbdbL,
- 0x5579c0bdL, 0x1a60320aL, 0xd6a100c6L, 0x402c7279L,
- 0x679f25feL, 0xfb1fa3ccL, 0x8ea5e9f8L, 0xdb3222f8L,
- 0x3c7516dfL, 0xfd616b15L, 0x2f501ec8L, 0xad0552abL,
- 0x323db5faL, 0xfd238760L, 0x53317b48L, 0x3e00df82L,
- 0x9e5c57bbL, 0xca6f8ca0L, 0x1a87562eL, 0xdf1769dbL,
- 0xd542a8f6L, 0x287effc3L, 0xac6732c6L, 0x8c4f5573L,
- 0x695b27b0L, 0xbbca58c8L, 0xe1ffa35dL, 0xb8f011a0L,
- 0x10fa3d98L, 0xfd2183b8L, 0x4afcb56cL, 0x2dd1d35bL,
- 0x9a53e479L, 0xb6f84565L, 0xd28e49bcL, 0x4bfb9790L,
- 0xe1ddf2daL, 0xa4cb7e33L, 0x62fb1341L, 0xcee4c6e8L,
- 0xef20cadaL, 0x36774c01L, 0xd07e9efeL, 0x2bf11fb4L,
- 0x95dbda4dL, 0xae909198L, 0xeaad8e71L, 0x6b93d5a0L,
- 0xd08ed1d0L, 0xafc725e0L, 0x8e3c5b2fL, 0x8e7594b7L,
- 0x8ff6e2fbL, 0xf2122b64L, 0x8888b812L, 0x900df01cL,
- 0x4fad5ea0L, 0x688fc31cL, 0xd1cff191L, 0xb3a8c1adL,
- 0x2f2f2218L, 0xbe0e1777L, 0xea752dfeL, 0x8b021fa1L,
- 0xe5a0cc0fL, 0xb56f74e8L, 0x18acf3d6L, 0xce89e299L,
- 0xb4a84fe0L, 0xfd13e0b7L, 0x7cc43b81L, 0xd2ada8d9L,
- 0x165fa266L, 0x80957705L, 0x93cc7314L, 0x211a1477L,
- 0xe6ad2065L, 0x77b5fa86L, 0xc75442f5L, 0xfb9d35cfL,
- 0xebcdaf0cL, 0x7b3e89a0L, 0xd6411bd3L, 0xae1e7e49L,
- 0x00250e2dL, 0x2071b35eL, 0x226800bbL, 0x57b8e0afL,
- 0x2464369bL, 0xf009b91eL, 0x5563911dL, 0x59dfa6aaL,
- 0x78c14389L, 0xd95a537fL, 0x207d5ba2L, 0x02e5b9c5L,
- 0x83260376L, 0x6295cfa9L, 0x11c81968L, 0x4e734a41L,
- 0xb3472dcaL, 0x7b14a94aL, 0x1b510052L, 0x9a532915L,
- 0xd60f573fL, 0xbc9bc6e4L, 0x2b60a476L, 0x81e67400L,
- 0x08ba6fb5L, 0x571be91fL, 0xf296ec6bL, 0x2a0dd915L,
- 0xb6636521L, 0xe7b9f9b6L, 0xff34052eL, 0xc5855664L,
- 0x53b02d5dL, 0xa99f8fa1L, 0x08ba4799L, 0x6e85076aL,
- 0x4b7a70e9L, 0xb5b32944L, 0xdb75092eL, 0xc4192623L,
- 0xad6ea6b0L, 0x49a7df7dL, 0x9cee60b8L, 0x8fedb266L,
- 0xecaa8c71L, 0x699a17ffL, 0x5664526cL, 0xc2b19ee1L,
- 0x193602a5L, 0x75094c29L, 0xa0591340L, 0xe4183a3eL,
- 0x3f54989aL, 0x5b429d65L, 0x6b8fe4d6L, 0x99f73fd6L,
- 0xa1d29c07L, 0xefe830f5L, 0x4d2d38e6L, 0xf0255dc1L,
- 0x4cdd2086L, 0x8470eb26L, 0x6382e9c6L, 0x021ecc5eL,
- 0x09686b3fL, 0x3ebaefc9L, 0x3c971814L, 0x6b6a70a1L,
- 0x687f3584L, 0x52a0e286L, 0xb79c5305L, 0xaa500737L,
- 0x3e07841cL, 0x7fdeae5cL, 0x8e7d44ecL, 0x5716f2b8L,
- 0xb03ada37L, 0xf0500c0dL, 0xf01c1f04L, 0x0200b3ffL,
- 0xae0cf51aL, 0x3cb574b2L, 0x25837a58L, 0xdc0921bdL,
- 0xd19113f9L, 0x7ca92ff6L, 0x94324773L, 0x22f54701L,
- 0x3ae5e581L, 0x37c2dadcL, 0xc8b57634L, 0x9af3dda7L,
- 0xa9446146L, 0x0fd0030eL, 0xecc8c73eL, 0xa4751e41L,
- 0xe238cd99L, 0x3bea0e2fL, 0x3280bba1L, 0x183eb331L,
- 0x4e548b38L, 0x4f6db908L, 0x6f420d03L, 0xf60a04bfL,
- 0x2cb81290L, 0x24977c79L, 0x5679b072L, 0xbcaf89afL,
- 0xde9a771fL, 0xd9930810L, 0xb38bae12L, 0xdccf3f2eL,
- 0x5512721fL, 0x2e6b7124L, 0x501adde6L, 0x9f84cd87L,
- 0x7a584718L, 0x7408da17L, 0xbc9f9abcL, 0xe94b7d8cL,
- 0xec7aec3aL, 0xdb851dfaL, 0x63094366L, 0xc464c3d2L,
- 0xef1c1847L, 0x3215d908L, 0xdd433b37L, 0x24c2ba16L,
- 0x12a14d43L, 0x2a65c451L, 0x50940002L, 0x133ae4ddL,
- 0x71dff89eL, 0x10314e55L, 0x81ac77d6L, 0x5f11199bL,
- 0x043556f1L, 0xd7a3c76bL, 0x3c11183bL, 0x5924a509L,
- 0xf28fe6edL, 0x97f1fbfaL, 0x9ebabf2cL, 0x1e153c6eL,
- 0x86e34570L, 0xeae96fb1L, 0x860e5e0aL, 0x5a3e2ab3L,
- 0x771fe71cL, 0x4e3d06faL, 0x2965dcb9L, 0x99e71d0fL,
- 0x803e89d6L, 0x5266c825L, 0x2e4cc978L, 0x9c10b36aL,
- 0xc6150ebaL, 0x94e2ea78L, 0xa5fc3c53L, 0x1e0a2df4L,
- 0xf2f74ea7L, 0x361d2b3dL, 0x1939260fL, 0x19c27960L,
- 0x5223a708L, 0xf71312b6L, 0xebadfe6eL, 0xeac31f66L,
- 0xe3bc4595L, 0xa67bc883L, 0xb17f37d1L, 0x018cff28L,
- 0xc332ddefL, 0xbe6c5aa5L, 0x65582185L, 0x68ab9802L,
- 0xeecea50fL, 0xdb2f953bL, 0x2aef7dadL, 0x5b6e2f84L,
- 0x1521b628L, 0x29076170L, 0xecdd4775L, 0x619f1510L,
- 0x13cca830L, 0xeb61bd96L, 0x0334fe1eL, 0xaa0363cfL,
- 0xb5735c90L, 0x4c70a239L, 0xd59e9e0bL, 0xcbaade14L,
- 0xeecc86bcL, 0x60622ca7L, 0x9cab5cabL, 0xb2f3846eL,
- 0x648b1eafL, 0x19bdf0caL, 0xa02369b9L, 0x655abb50L,
- 0x40685a32L, 0x3c2ab4b3L, 0x319ee9d5L, 0xc021b8f7L,
- 0x9b540b19L, 0x875fa099L, 0x95f7997eL, 0x623d7da8L,
- 0xf837889aL, 0x97e32d77L, 0x11ed935fL, 0x16681281L,
- 0x0e358829L, 0xc7e61fd6L, 0x96dedfa1L, 0x7858ba99L,
- 0x57f584a5L, 0x1b227263L, 0x9b83c3ffL, 0x1ac24696L,
- 0xcdb30aebL, 0x532e3054L, 0x8fd948e4L, 0x6dbc3128L,
- 0x58ebf2efL, 0x34c6ffeaL, 0xfe28ed61L, 0xee7c3c73L,
- 0x5d4a14d9L, 0xe864b7e3L, 0x42105d14L, 0x203e13e0L,
- 0x45eee2b6L, 0xa3aaabeaL, 0xdb6c4f15L, 0xfacb4fd0L,
- 0xc742f442L, 0xef6abbb5L, 0x654f3b1dL, 0x41cd2105L,
- 0xd81e799eL, 0x86854dc7L, 0xe44b476aL, 0x3d816250L,
- 0xcf62a1f2L, 0x5b8d2646L, 0xfc8883a0L, 0xc1c7b6a3L,
- 0x7f1524c3L, 0x69cb7492L, 0x47848a0bL, 0x5692b285L,
- 0x095bbf00L, 0xad19489dL, 0x1462b174L, 0x23820e00L,
- 0x58428d2aL, 0x0c55f5eaL, 0x1dadf43eL, 0x233f7061L,
- 0x3372f092L, 0x8d937e41L, 0xd65fecf1L, 0x6c223bdbL,
- 0x7cde3759L, 0xcbee7460L, 0x4085f2a7L, 0xce77326eL,
- 0xa6078084L, 0x19f8509eL, 0xe8efd855L, 0x61d99735L,
- 0xa969a7aaL, 0xc50c06c2L, 0x5a04abfcL, 0x800bcadcL,
- 0x9e447a2eL, 0xc3453484L, 0xfdd56705L, 0x0e1e9ec9L,
- 0xdb73dbd3L, 0x105588cdL, 0x675fda79L, 0xe3674340L,
- 0xc5c43465L, 0x713e38d8L, 0x3d28f89eL, 0xf16dff20L,
- 0x153e21e7L, 0x8fb03d4aL, 0xe6e39f2bL, 0xdb83adf7L,
- 0xe93d5a68L, 0x948140f7L, 0xf64c261cL, 0x94692934L,
- 0x411520f7L, 0x7602d4f7L, 0xbcf46b2eL, 0xd4a20068L,
- 0xd4082471L, 0x3320f46aL, 0x43b7d4b7L, 0x500061afL,
- 0x1e39f62eL, 0x97244546L, 0x14214f74L, 0xbf8b8840L,
- 0x4d95fc1dL, 0x96b591afL, 0x70f4ddd3L, 0x66a02f45L,
- 0xbfbc09ecL, 0x03bd9785L, 0x7fac6dd0L, 0x31cb8504L,
- 0x96eb27b3L, 0x55fd3941L, 0xda2547e6L, 0xabca0a9aL,
- 0x28507825L, 0x530429f4L, 0x0a2c86daL, 0xe9b66dfbL,
- 0x68dc1462L, 0xd7486900L, 0x680ec0a4L, 0x27a18deeL,
- 0x4f3ffea2L, 0xe887ad8cL, 0xb58ce006L, 0x7af4d6b6L,
- 0xaace1e7cL, 0xd3375fecL, 0xce78a399L, 0x406b2a42L,
- 0x20fe9e35L, 0xd9f385b9L, 0xee39d7abL, 0x3b124e8bL,
- 0x1dc9faf7L, 0x4b6d1856L, 0x26a36631L, 0xeae397b2L,
- 0x3a6efa74L, 0xdd5b4332L, 0x6841e7f7L, 0xca7820fbL,
- 0xfb0af54eL, 0xd8feb397L, 0x454056acL, 0xba489527L,
- 0x55533a3aL, 0x20838d87L, 0xfe6ba9b7L, 0xd096954bL,
- 0x55a867bcL, 0xa1159a58L, 0xcca92963L, 0x99e1db33L,
- 0xa62a4a56L, 0x3f3125f9L, 0x5ef47e1cL, 0x9029317cL,
- 0xfdf8e802L, 0x04272f70L, 0x80bb155cL, 0x05282ce3L,
- 0x95c11548L, 0xe4c66d22L, 0x48c1133fL, 0xc70f86dcL,
- 0x07f9c9eeL, 0x41041f0fL, 0x404779a4L, 0x5d886e17L,
- 0x325f51ebL, 0xd59bc0d1L, 0xf2bcc18fL, 0x41113564L,
- 0x257b7834L, 0x602a9c60L, 0xdff8e8a3L, 0x1f636c1bL,
- 0x0e12b4c2L, 0x02e1329eL, 0xaf664fd1L, 0xcad18115L,
- 0x6b2395e0L, 0x333e92e1L, 0x3b240b62L, 0xeebeb922L,
- 0x85b2a20eL, 0xe6ba0d99L, 0xde720c8cL, 0x2da2f728L,
- 0xd0127845L, 0x95b794fdL, 0x647d0862L, 0xe7ccf5f0L,
- 0x5449a36fL, 0x877d48faL, 0xc39dfd27L, 0xf33e8d1eL,
- 0x0a476341L, 0x992eff74L, 0x3a6f6eabL, 0xf4f8fd37L,
- 0xa812dc60L, 0xa1ebddf8L, 0x991be14cL, 0xdb6e6b0dL,
- 0xc67b5510L, 0x6d672c37L, 0x2765d43bL, 0xdcd0e804L,
- 0xf1290dc7L, 0xcc00ffa3L, 0xb5390f92L, 0x690fed0bL,
- 0x667b9ffbL, 0xcedb7d9cL, 0xa091cf0bL, 0xd9155ea3L,
- 0xbb132f88L, 0x515bad24L, 0x7b9479bfL, 0x763bd6ebL,
- 0x37392eb3L, 0xcc115979L, 0x8026e297L, 0xf42e312dL,
- 0x6842ada7L, 0xc66a2b3bL, 0x12754cccL, 0x782ef11cL,
- 0x6a124237L, 0xb79251e7L, 0x06a1bbe6L, 0x4bfb6350L,
- 0x1a6b1018L, 0x11caedfaL, 0x3d25bdd8L, 0xe2e1c3c9L,
- 0x44421659L, 0x0a121386L, 0xd90cec6eL, 0xd5abea2aL,
- 0x64af674eL, 0xda86a85fL, 0xbebfe988L, 0x64e4c3feL,
- 0x9dbc8057L, 0xf0f7c086L, 0x60787bf8L, 0x6003604dL,
- 0xd1fd8346L, 0xf6381fb0L, 0x7745ae04L, 0xd736fcccL,
- 0x83426b33L, 0xf01eab71L, 0xb0804187L, 0x3c005e5fL,
- 0x77a057beL, 0xbde8ae24L, 0x55464299L, 0xbf582e61L,
- 0x4e58f48fL, 0xf2ddfda2L, 0xf474ef38L, 0x8789bdc2L,
- 0x5366f9c3L, 0xc8b38e74L, 0xb475f255L, 0x46fcd9b9L,
- 0x7aeb2661L, 0x8b1ddf84L, 0x846a0e79L, 0x915f95e2L,
- 0x466e598eL, 0x20b45770L, 0x8cd55591L, 0xc902de4cL,
- 0xb90bace1L, 0xbb8205d0L, 0x11a86248L, 0x7574a99eL,
- 0xb77f19b6L, 0xe0a9dc09L, 0x662d09a1L, 0xc4324633L,
- 0xe85a1f02L, 0x09f0be8cL, 0x4a99a025L, 0x1d6efe10L,
- 0x1ab93d1dL, 0x0ba5a4dfL, 0xa186f20fL, 0x2868f169L,
- 0xdcb7da83L, 0x573906feL, 0xa1e2ce9bL, 0x4fcd7f52L,
- 0x50115e01L, 0xa70683faL, 0xa002b5c4L, 0x0de6d027L,
- 0x9af88c27L, 0x773f8641L, 0xc3604c06L, 0x61a806b5L,
- 0xf0177a28L, 0xc0f586e0L, 0x006058aaL, 0x30dc7d62L,
- 0x11e69ed7L, 0x2338ea63L, 0x53c2dd94L, 0xc2c21634L,
- 0xbbcbee56L, 0x90bcb6deL, 0xebfc7da1L, 0xce591d76L,
- 0x6f05e409L, 0x4b7c0188L, 0x39720a3dL, 0x7c927c24L,
- 0x86e3725fL, 0x724d9db9L, 0x1ac15bb4L, 0xd39eb8fcL,
- 0xed545578L, 0x08fca5b5L, 0xd83d7cd3L, 0x4dad0fc4L,
- 0x1e50ef5eL, 0xb161e6f8L, 0xa28514d9L, 0x6c51133cL,
- 0x6fd5c7e7L, 0x56e14ec4L, 0x362abfceL, 0xddc6c837L,
- 0xd79a3234L, 0x92638212L, 0x670efa8eL, 0x406000e0L,
- 0x3a39ce37L, 0xd3faf5cfL, 0xabc27737L, 0x5ac52d1bL,
- 0x5cb0679eL, 0x4fa33742L, 0xd3822740L, 0x99bc9bbeL,
- 0xd5118e9dL, 0xbf0f7315L, 0xd62d1c7eL, 0xc700c47bL,
- 0xb78c1b6bL, 0x21a19045L, 0xb26eb1beL, 0x6a366eb4L,
- 0x5748ab2fL, 0xbc946e79L, 0xc6a376d2L, 0x6549c2c8L,
- 0x530ff8eeL, 0x468dde7dL, 0xd5730a1dL, 0x4cd04dc6L,
- 0x2939bbdbL, 0xa9ba4650L, 0xac9526e8L, 0xbe5ee304L,
- 0xa1fad5f0L, 0x6a2d519aL, 0x63ef8ce2L, 0x9a86ee22L,
- 0xc089c2b8L, 0x43242ef6L, 0xa51e03aaL, 0x9cf2d0a4L,
- 0x83c061baL, 0x9be96a4dL, 0x8fe51550L, 0xba645bd6L,
- 0x2826a2f9L, 0xa73a3ae1L, 0x4ba99586L, 0xef5562e9L,
- 0xc72fefd3L, 0xf752f7daL, 0x3f046f69L, 0x77fa0a59L,
- 0x80e4a915L, 0x87b08601L, 0x9b09e6adL, 0x3b3ee593L,
- 0xe990fd5aL, 0x9e34d797L, 0x2cf0b7d9L, 0x022b8b51L,
- 0x96d5ac3aL, 0x017da67dL, 0xd1cf3ed6L, 0x7c7d2d28L,
- 0x1f9f25cfL, 0xadf2b89bL, 0x5ad6b472L, 0x5a88f54cL,
- 0xe029ac71L, 0xe019a5e6L, 0x47b0acfdL, 0xed93fa9bL,
- 0xe8d3c48dL, 0x283b57ccL, 0xf8d56629L, 0x79132e28L,
- 0x785f0191L, 0xed756055L, 0xf7960e44L, 0xe3d35e8cL,
- 0x15056dd4L, 0x88f46dbaL, 0x03a16125L, 0x0564f0bdL,
- 0xc3eb9e15L, 0x3c9057a2L, 0x97271aecL, 0xa93a072aL,
- 0x1b3f6d9bL, 0x1e6321f5L, 0xf59c66fbL, 0x26dcf319L,
- 0x7533d928L, 0xb155fdf5L, 0x03563482L, 0x8aba3cbbL,
- 0x28517711L, 0xc20ad9f8L, 0xabcc5167L, 0xccad925fL,
- 0x4de81751L, 0x3830dc8eL, 0x379d5862L, 0x9320f991L,
- 0xea7a90c2L, 0xfb3e7bceL, 0x5121ce64L, 0x774fbe32L,
- 0xa8b6e37eL, 0xc3293d46L, 0x48de5369L, 0x6413e680L,
- 0xa2ae0810L, 0xdd6db224L, 0x69852dfdL, 0x09072166L,
- 0xb39a460aL, 0x6445c0ddL, 0x586cdecfL, 0x1c20c8aeL,
- 0x5bbef7ddL, 0x1b588d40L, 0xccd2017fL, 0x6bb4e3bbL,
- 0xdda26a7eL, 0x3a59ff45L, 0x3e350a44L, 0xbcb4cdd5L,
- 0x72eacea8L, 0xfa6484bbL, 0x8d6612aeL, 0xbf3c6f47L,
- 0xd29be463L, 0x542f5d9eL, 0xaec2771bL, 0xf64e6370L,
- 0x740e0d8dL, 0xe75b1357L, 0xf8721671L, 0xaf537d5dL,
- 0x4040cb08L, 0x4eb4e2ccL, 0x34d2466aL, 0x0115af84L,
- 0xe1b00428L, 0x95983a1dL, 0x06b89fb4L, 0xce6ea048L,
- 0x6f3f3b82L, 0x3520ab82L, 0x011a1d4bL, 0x277227f8L,
- 0x611560b1L, 0xe7933fdcL, 0xbb3a792bL, 0x344525bdL,
- 0xa08839e1L, 0x51ce794bL, 0x2f32c9b7L, 0xa01fbac9L,
- 0xe01cc87eL, 0xbcc7d1f6L, 0xcf0111c3L, 0xa1e8aac7L,
- 0x1a908749L, 0xd44fbd9aL, 0xd0dadecbL, 0xd50ada38L,
- 0x0339c32aL, 0xc6913667L, 0x8df9317cL, 0xe0b12b4fL,
- 0xf79e59b7L, 0x43f5bb3aL, 0xf2d519ffL, 0x27d9459cL,
- 0xbf97222cL, 0x15e6fc2aL, 0x0f91fc71L, 0x9b941525L,
- 0xfae59361L, 0xceb69cebL, 0xc2a86459L, 0x12baa8d1L,
- 0xb6c1075eL, 0xe3056a0cL, 0x10d25065L, 0xcb03a442L,
- 0xe0ec6e0eL, 0x1698db3bL, 0x4c98a0beL, 0x3278e964L,
- 0x9f1f9532L, 0xe0d392dfL, 0xd3a0342bL, 0x8971f21eL,
- 0x1b0a7441L, 0x4ba3348cL, 0xc5be7120L, 0xc37632d8L,
- 0xdf359f8dL, 0x9b992f2eL, 0xe60b6f47L, 0x0fe3f11dL,
- 0xe54cda54L, 0x1edad891L, 0xce6279cfL, 0xcd3e7e6fL,
- 0x1618b166L, 0xfd2c1d05L, 0x848fd2c5L, 0xf6fb2299L,
- 0xf523f357L, 0xa6327623L, 0x93a83531L, 0x56cccd02L,
- 0xacf08162L, 0x5a75ebb5L, 0x6e163697L, 0x88d273ccL,
- 0xde966292L, 0x81b949d0L, 0x4c50901bL, 0x71c65614L,
- 0xe6c6c7bdL, 0x327a140aL, 0x45e1d006L, 0xc3f27b9aL,
- 0xc9aa53fdL, 0x62a80f00L, 0xbb25bfe2L, 0x35bdd2f6L,
- 0x71126905L, 0xb2040222L, 0xb6cbcf7cL, 0xcd769c2bL,
- 0x53113ec0L, 0x1640e3d3L, 0x38abbd60L, 0x2547adf0L,
- 0xba38209cL, 0xf746ce76L, 0x77afa1c5L, 0x20756060L,
- 0x85cbfe4eL, 0x8ae88dd8L, 0x7aaaf9b0L, 0x4cf9aa7eL,
- 0x1948c25cL, 0x02fb8a8cL, 0x01c36ae4L, 0xd6ebe1f9L,
- 0x90d4f869L, 0xa65cdea0L, 0x3f09252dL, 0xc208e69fL,
- 0xb74e6132L, 0xce77e25bL, 0x578fdfe3L, 0x3ac372e6L,
-};
-
--- a/libsec/ccpoly.c
+++ /dev/null
@@ -1,90 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-static void
-ccpolyotk(Chachastate *cs, DigestState *ds)
-{
- uchar otk[ChachaBsize];
-
- memset(ds, 0, sizeof(*ds));
- memset(otk, 0, 32);
- chacha_setblock(cs, 0);
- chacha_encrypt(otk, ChachaBsize, cs);
- poly1305(nil, 0, otk, 32, nil, ds);
-}
-
-static void
-ccpolypad(uchar *buf, ulong nbuf, DigestState *ds)
-{
- static uchar zeros[16] = {0};
- ulong npad;
-
- if(nbuf == 0)
- return;
- poly1305(buf, nbuf, nil, 0, nil, ds);
- npad = nbuf % 16;
- if(npad == 0)
- return;
- poly1305(zeros, 16 - npad, nil, 0, nil, ds);
-}
-
-static void
-ccpolylen(ulong n, uchar tag[16], DigestState *ds)
-{
- uchar info[8];
-
- info[0] = n;
- info[1] = n>>8;
- info[2] = n>>16;
- info[3] = n>>24;
- info[4] = 0;
- info[5] = 0;
- info[6] = 0;
- info[7] = 0;
- poly1305(info, 8, nil, 0, tag, ds);
-}
-
-void
-ccpoly_encrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], Chachastate *cs)
-{
- DigestState ds;
-
- ccpolyotk(cs, &ds);
- if(cs->ivwords == 2){
- poly1305(aad, naad, nil, 0, nil, &ds);
- ccpolylen(naad, nil, &ds);
- chacha_encrypt(dat, ndat, cs);
- poly1305(dat, ndat, nil, 0, nil, &ds);
- ccpolylen(ndat, tag, &ds);
- } else {
- ccpolypad(aad, naad, &ds);
- chacha_encrypt(dat, ndat, cs);
- ccpolypad(dat, ndat, &ds);
- ccpolylen(naad, nil, &ds);
- ccpolylen(ndat, tag, &ds);
- }
-}
-
-int
-ccpoly_decrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], Chachastate *cs)
-{
- DigestState ds;
- uchar tmp[16];
-
- ccpolyotk(cs, &ds);
- if(cs->ivwords == 2){
- poly1305(aad, naad, nil, 0, nil, &ds);
- ccpolylen(naad, nil, &ds);
- poly1305(dat, ndat, nil, 0, nil, &ds);
- ccpolylen(ndat, tmp, &ds);
- } else {
- ccpolypad(aad, naad, &ds);
- ccpolypad(dat, ndat, &ds);
- ccpolylen(naad, nil, &ds);
- ccpolylen(ndat, tmp, &ds);
- }
- if(tsmemcmp(tag, tmp, 16) != 0)
- return -1;
- chacha_encrypt(dat, ndat, cs);
- return 0;
-}
--- a/libsec/chacha.c
+++ /dev/null
@@ -1,222 +1,0 @@
-/*
-Adapted from chacha-merged.c version 20080118
-D. J. Bernstein
-Public domain.
-
-modified for use in Plan 9 and Inferno (no algorithmic changes),
-and including the changes to block number and nonce defined in RFC7539
-*/
-
-#include "os.h"
-#include <libsec.h>
-
-/* from chachablock.$O */
-extern void _chachablock(u32int x[16], int rounds);
-
-/* little-endian data order */
-#define GET4(p) ((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24))
-#define PUT4(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24
-
-#define ENCRYPT(s, x, y, d) {\
- u32int v; \
- v = GET4(s); \
- v ^= (x)+(y); \
- PUT4(d, v); \
-}
-
-static uchar sigma[16] = "expand 32-byte k";
-static uchar tau[16] = "expand 16-byte k";
-
-static void
-load(u32int *d, uchar *s, int nw)
-{
- int i;
-
- for(i = 0; i < nw; i++, s+=4)
- d[i] = GET4(s);
-}
-
-void
-setupChachastate(Chachastate *s, uchar *key, ulong keylen, uchar *iv, ulong ivlen, int rounds)
-{
- if(keylen != 256/8 && keylen != 128/8)
- sysfatal("invalid chacha key length");
- if(ivlen != 64/8 && ivlen != 96/8
- && ivlen != 128/8 && ivlen != 192/8) /* hchacha, xchacha */
- sysfatal("invalid chacha iv length");
- if(rounds == 0)
- rounds = 20;
- s->rounds = rounds;
- if(keylen == 256/8) { /* recommended */
- load(&s->input[0], sigma, 4);
- load(&s->input[4], key, 8);
- }else{
- load(&s->input[0], tau, 4);
- load(&s->input[4], key, 4);
- load(&s->input[8], key, 4);
- }
- s->xkey[0] = s->input[4];
- s->xkey[1] = s->input[5];
- s->xkey[2] = s->input[6];
- s->xkey[3] = s->input[7];
- s->xkey[4] = s->input[8];
- s->xkey[5] = s->input[9];
- s->xkey[6] = s->input[10];
- s->xkey[7] = s->input[11];
-
- s->ivwords = ivlen/4;
- s->input[12] = 0;
- s->input[13] = 0;
- if(iv == nil){
- s->input[14] = 0;
- s->input[15] = 0;
- }else
- chacha_setiv(s, iv);
-}
-
-static void
-hchachablock(uchar h[32], Chachastate *s)
-{
- u32int x[16];
-
- x[0] = s->input[0];
- x[1] = s->input[1];
- x[2] = s->input[2];
- x[3] = s->input[3];
- x[4] = s->input[4];
- x[5] = s->input[5];
- x[6] = s->input[6];
- x[7] = s->input[7];
- x[8] = s->input[8];
- x[9] = s->input[9];
- x[10] = s->input[10];
- x[11] = s->input[11];
- x[12] = s->input[12];
- x[13] = s->input[13];
- x[14] = s->input[14];
- x[15] = s->input[15];
-
- _chachablock(x, s->rounds);
-
- PUT4(h+0*4, x[0]);
- PUT4(h+1*4, x[1]);
- PUT4(h+2*4, x[2]);
- PUT4(h+3*4, x[3]);
- PUT4(h+4*4, x[12]);
- PUT4(h+5*4, x[13]);
- PUT4(h+6*4, x[14]);
- PUT4(h+7*4, x[15]);
-}
-
-void
-chacha_setiv(Chachastate *s, uchar *iv)
-{
- if(s->ivwords == 192/32){
- /* xchacha with 192-bit iv */
- u32int counter[2];
- uchar h[32];
-
- s->input[4] = s->xkey[0];
- s->input[5] = s->xkey[1];
- s->input[6] = s->xkey[2];
- s->input[7] = s->xkey[3];
- s->input[8] = s->xkey[4];
- s->input[9] = s->xkey[5];
- s->input[10] = s->xkey[6];
- s->input[11] = s->xkey[7];
-
- counter[0] = s->input[12];
- counter[1] = s->input[13];
-
- load(&s->input[12], iv, 4);
-
- hchachablock(h, s);
- load(&s->input[4], h, 8);
- memset(h, 0, 32);
-
- s->input[12] = counter[0];
- s->input[13] = counter[1];
-
- load(&s->input[14], iv+16, 2);
- return;
- }
- load(&s->input[16 - s->ivwords], iv, s->ivwords);
-}
-
-void
-chacha_setblock(Chachastate *s, u64int blockno)
-{
- s->input[12] = blockno;
- if(s->ivwords != 3)
- s->input[13] = blockno>>32;
-}
-
-static void
-encryptblock(Chachastate *s, uchar *src, uchar *dst)
-{
- u32int x[16];
- int i;
-
- x[0] = s->input[0];
- x[1] = s->input[1];
- x[2] = s->input[2];
- x[3] = s->input[3];
- x[4] = s->input[4];
- x[5] = s->input[5];
- x[6] = s->input[6];
- x[7] = s->input[7];
- x[8] = s->input[8];
- x[9] = s->input[9];
- x[10] = s->input[10];
- x[11] = s->input[11];
- x[12] = s->input[12];
- x[13] = s->input[13];
- x[14] = s->input[14];
- x[15] = s->input[15];
- _chachablock(x, s->rounds);
-
- for(i=0; i<nelem(x); i+=4){
- ENCRYPT(src, x[i], s->input[i], dst);
- ENCRYPT(src+4, x[i+1], s->input[i+1], dst+4);
- ENCRYPT(src+8, x[i+2], s->input[i+2], dst+8);
- ENCRYPT(src+12, x[i+3], s->input[i+3], dst+12);
- src += 16;
- dst += 16;
- }
-
- if(++s->input[12] == 0 && s->ivwords != 3)
- s->input[13]++;
-}
-
-void
-chacha_encrypt2(uchar *src, uchar *dst, ulong bytes, Chachastate *s)
-{
- uchar tmp[ChachaBsize];
-
- for(; bytes >= ChachaBsize; bytes -= ChachaBsize){
- encryptblock(s, src, dst);
- src += ChachaBsize;
- dst += ChachaBsize;
- }
- if(bytes > 0){
- memmove(tmp, src, bytes);
- encryptblock(s, tmp, tmp);
- memmove(dst, tmp, bytes);
- }
-}
-
-void
-chacha_encrypt(uchar *buf, ulong bytes, Chachastate *s)
-{
- chacha_encrypt2(buf, buf, bytes, s);
-}
-
-void
-hchacha(uchar h[32], uchar *key, ulong keylen, uchar nonce[16], int rounds)
-{
- Chachastate s[1];
-
- setupChachastate(s, key, keylen, nonce, 16, rounds);
- hchachablock(h, s);
- memset(s, 0, sizeof(s));
-}
--- a/libsec/chachablock.c
+++ /dev/null
@@ -1,29 +1,0 @@
-#include "os.h"
-
-#define ROTATE(v,c) ((u32int)((v) << (c)) | ((v) >> (32 - (c))))
-
-#define QUARTERROUND(ia,ib,ic,id) { \
- u32int a, b, c, d, t; \
- a = x[ia]; b = x[ib]; c = x[ic]; d = x[id]; \
- a += b; t = d^a; d = ROTATE(t,16); \
- c += d; t = b^c; b = ROTATE(t,12); \
- a += b; t = d^a; d = ROTATE(t, 8); \
- c += d; t = b^c; b = ROTATE(t, 7); \
- x[ia] = a; x[ib] = b; x[ic] = c; x[id] = d; \
-}
-
-void
-_chachablock(u32int x[16], int rounds)
-{
- for(; rounds > 0; rounds -= 2) {
- QUARTERROUND(0, 4, 8,12)
- QUARTERROUND(1, 5, 9,13)
- QUARTERROUND(2, 6,10,14)
- QUARTERROUND(3, 7,11,15)
-
- QUARTERROUND(0, 5,10,15)
- QUARTERROUND(1, 6,11,12)
- QUARTERROUND(2, 7, 8,13)
- QUARTERROUND(3, 4, 9,14)
- }
-}
--- a/libsec/curve25519.c
+++ /dev/null
@@ -1,570 +1,0 @@
-/* Copyright 2008, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * curve25519: Curve25519 elliptic curve, public key function
- *
- * http://code.google.com/p/curve25519-donna/
- *
- * Adam Langley <agl@imperialviolet.org>
- *
- * Derived from public domain C code by Daniel J. Bernstein <djb@cr.yp.to>
- *
- * More information about curve25519 can be found here
- * http://cr.yp.to/ecdh.html
- *
- * djb's sample implementation of curve25519 is written in a special assembly
- * language called qhasm and uses the floating point registers.
- *
- * This is, almost, a clean room reimplementation from the curve25519 paper. It
- * uses many of the tricks described therein. Only the crecip function is taken
- * from the sample implementation.
- */
-#include "os.h"
-#include <libsec.h>
-
-typedef vlong felem;
-
-/* Sum two numbers: output += in */
-static void fsum(felem *output, felem *in) {
- unsigned i;
- for (i = 0; i < 10; i += 2) {
- output[0+i] = (output[0+i] + in[0+i]);
- output[1+i] = (output[1+i] + in[1+i]);
- }
-}
-
-/* Find the difference of two numbers: output = in - output
- * (note the order of the arguments!)
- */
-static void fdifference(felem *output, felem *in) {
- unsigned i;
- for (i = 0; i < 10; ++i) {
- output[i] = (in[i] - output[i]);
- }
-}
-
-/* Multiply a number my a scalar: output = in * scalar */
-static void fscalar_product(felem *output, felem *in, felem scalar) {
- unsigned i;
- for (i = 0; i < 10; ++i) {
- output[i] = in[i] * scalar;
- }
-}
-
-/* Multiply two numbers: output = in2 * in
- *
- * output must be distinct to both inputs. The inputs are reduced coefficient
- * form, the output is not.
- */
-static void fproduct(felem *output, felem *in2, felem *in) {
- output[0] = in2[0] * in[0];
- output[1] = in2[0] * in[1] +
- in2[1] * in[0];
- output[2] = 2 * in2[1] * in[1] +
- in2[0] * in[2] +
- in2[2] * in[0];
- output[3] = in2[1] * in[2] +
- in2[2] * in[1] +
- in2[0] * in[3] +
- in2[3] * in[0];
- output[4] = in2[2] * in[2] +
- 2 * (in2[1] * in[3] +
- in2[3] * in[1]) +
- in2[0] * in[4] +
- in2[4] * in[0];
- output[5] = in2[2] * in[3] +
- in2[3] * in[2] +
- in2[1] * in[4] +
- in2[4] * in[1] +
- in2[0] * in[5] +
- in2[5] * in[0];
- output[6] = 2 * (in2[3] * in[3] +
- in2[1] * in[5] +
- in2[5] * in[1]) +
- in2[2] * in[4] +
- in2[4] * in[2] +
- in2[0] * in[6] +
- in2[6] * in[0];
- output[7] = in2[3] * in[4] +
- in2[4] * in[3] +
- in2[2] * in[5] +
- in2[5] * in[2] +
- in2[1] * in[6] +
- in2[6] * in[1] +
- in2[0] * in[7] +
- in2[7] * in[0];
- output[8] = in2[4] * in[4] +
- 2 * (in2[3] * in[5] +
- in2[5] * in[3] +
- in2[1] * in[7] +
- in2[7] * in[1]) +
- in2[2] * in[6] +
- in2[6] * in[2] +
- in2[0] * in[8] +
- in2[8] * in[0];
- output[9] = in2[4] * in[5] +
- in2[5] * in[4] +
- in2[3] * in[6] +
- in2[6] * in[3] +
- in2[2] * in[7] +
- in2[7] * in[2] +
- in2[1] * in[8] +
- in2[8] * in[1] +
- in2[0] * in[9] +
- in2[9] * in[0];
- output[10] = 2 * (in2[5] * in[5] +
- in2[3] * in[7] +
- in2[7] * in[3] +
- in2[1] * in[9] +
- in2[9] * in[1]) +
- in2[4] * in[6] +
- in2[6] * in[4] +
- in2[2] * in[8] +
- in2[8] * in[2];
- output[11] = in2[5] * in[6] +
- in2[6] * in[5] +
- in2[4] * in[7] +
- in2[7] * in[4] +
- in2[3] * in[8] +
- in2[8] * in[3] +
- in2[2] * in[9] +
- in2[9] * in[2];
- output[12] = in2[6] * in[6] +
- 2 * (in2[5] * in[7] +
- in2[7] * in[5] +
- in2[3] * in[9] +
- in2[9] * in[3]) +
- in2[4] * in[8] +
- in2[8] * in[4];
- output[13] = in2[6] * in[7] +
- in2[7] * in[6] +
- in2[5] * in[8] +
- in2[8] * in[5] +
- in2[4] * in[9] +
- in2[9] * in[4];
- output[14] = 2 * (in2[7] * in[7] +
- in2[5] * in[9] +
- in2[9] * in[5]) +
- in2[6] * in[8] +
- in2[8] * in[6];
- output[15] = in2[7] * in[8] +
- in2[8] * in[7] +
- in2[6] * in[9] +
- in2[9] * in[6];
- output[16] = in2[8] * in[8] +
- 2 * (in2[7] * in[9] +
- in2[9] * in[7]);
- output[17] = in2[8] * in[9] +
- in2[9] * in[8];
- output[18] = 2 * in2[9] * in[9];
-}
-
-/* Reduce a long form to a short form by taking the input mod 2^255 - 19. */
-static void freduce_degree(felem *output) {
- output[8] += 19 * output[18];
- output[7] += 19 * output[17];
- output[6] += 19 * output[16];
- output[5] += 19 * output[15];
- output[4] += 19 * output[14];
- output[3] += 19 * output[13];
- output[2] += 19 * output[12];
- output[1] += 19 * output[11];
- output[0] += 19 * output[10];
-}
-
-/* Reduce all coefficients of the short form input to be -2**25 <= x <= 2**25
- */
-static void freduce_coefficients(felem *output) {
- unsigned i;
- do {
- output[10] = 0;
-
- for (i = 0; i < 10; i += 2) {
- felem over = output[i] / 0x2000000l;
- felem over2 = (over + ((over >> 63) * 2) + 1) / 2;
- output[i+1] += over2;
- output[i] -= over2 * 0x4000000l;
-
- over = output[i+1] / 0x2000000;
- output[i+2] += over;
- output[i+1] -= over * 0x2000000;
- }
- output[0] += 19 * output[10];
- } while (output[10]);
-}
-
-/* A helpful wrapper around fproduct: output = in * in2.
- *
- * output must be distinct to both inputs. The output is reduced degree and
- * reduced coefficient.
- */
-static void
-fmul(felem *output, felem *in, felem *in2) {
- felem t[19];
- fproduct(t, in, in2);
- freduce_degree(t);
- freduce_coefficients(t);
- memcpy(output, t, sizeof(felem) * 10);
-}
-
-static void fsquare_inner(felem *output, felem *in) {
- felem tmp;
- output[0] = in[0] * in[0];
- output[1] = 2 * in[0] * in[1];
- output[2] = 2 * (in[1] * in[1] +
- in[0] * in[2]);
- output[3] = 2 * (in[1] * in[2] +
- in[0] * in[3]);
- output[4] = in[2] * in[2] +
- 4 * in[1] * in[3] +
- 2 * in[0] * in[4];
- output[5] = 2 * (in[2] * in[3] +
- in[1] * in[4] +
- in[0] * in[5]);
- output[6] = 2 * (in[3] * in[3] +
- in[2] * in[4] +
- in[0] * in[6] +
- 2 * in[1] * in[5]);
- output[7] = 2 * (in[3] * in[4] +
- in[2] * in[5] +
- in[1] * in[6] +
- in[0] * in[7]);
- tmp = in[1] * in[7] + in[3] * in[5];
- output[8] = in[4] * in[4] +
- 2 * (in[2] * in[6] +
- in[0] * in[8] +
- 2 * tmp);
- output[9] = 2 * (in[4] * in[5] +
- in[3] * in[6] +
- in[2] * in[7] +
- in[1] * in[8] +
- in[0] * in[9]);
- tmp = in[3] * in[7] + in[1] * in[9];
- output[10] = 2 * (in[5] * in[5] +
- in[4] * in[6] +
- in[2] * in[8] +
- 2 * tmp);
- output[11] = 2 * (in[5] * in[6] +
- in[4] * in[7] +
- in[3] * in[8] +
- in[2] * in[9]);
- output[12] = in[6] * in[6] +
- 2 * (in[4] * in[8] +
- 2 * (in[5] * in[7] +
- in[3] * in[9]));
- output[13] = 2 * (in[6] * in[7] +
- in[5] * in[8] +
- in[4] * in[9]);
- output[14] = 2 * (in[7] * in[7] +
- in[6] * in[8] +
- 2 * in[5] * in[9]);
- output[15] = 2 * (in[7] * in[8] +
- in[6] * in[9]);
- output[16] = in[8] * in[8] +
- 4 * in[7] * in[9];
- output[17] = 2 * in[8] * in[9];
- output[18] = 2 * in[9] * in[9];
-}
-
-static void
-fsquare(felem *output, felem *in) {
- felem t[19];
- fsquare_inner(t, in);
- freduce_degree(t);
- freduce_coefficients(t);
- memcpy(output, t, sizeof(felem) * 10);
-}
-
-/* Take a little-endian, 32-byte number and expand it into polynomial form */
-static void
-fexpand(felem *output, uchar *input) {
-#define F(n,start,shift,mask) \
- output[n] = ((((felem) input[start + 0]) | \
- ((felem) input[start + 1]) << 8 | \
- ((felem) input[start + 2]) << 16 | \
- ((felem) input[start + 3]) << 24) >> shift) & mask;
- F(0, 0, 0, 0x3ffffff);
- F(1, 3, 2, 0x1ffffff);
- F(2, 6, 3, 0x3ffffff);
- F(3, 9, 5, 0x1ffffff);
- F(4, 12, 6, 0x3ffffff);
- F(5, 16, 0, 0x1ffffff);
- F(6, 19, 1, 0x3ffffff);
- F(7, 22, 3, 0x1ffffff);
- F(8, 25, 4, 0x3ffffff);
- F(9, 28, 6, 0x1ffffff);
-#undef F
-}
-
-/* Take a fully reduced polynomial form number and contract it into a
- * little-endian, 32-byte array
- */
-static void
-fcontract(uchar *output, felem *input) {
- int i;
-
- do {
- for (i = 0; i < 9; ++i) {
- if ((i & 1) == 1) {
- while (input[i] < 0) {
- input[i] += 0x2000000;
- input[i + 1]--;
- }
- } else {
- while (input[i] < 0) {
- input[i] += 0x4000000;
- input[i + 1]--;
- }
- }
- }
- while (input[9] < 0) {
- input[9] += 0x2000000;
- input[0] -= 19;
- }
- } while (input[0] < 0);
-
- input[1] <<= 2;
- input[2] <<= 3;
- input[3] <<= 5;
- input[4] <<= 6;
- input[6] <<= 1;
- input[7] <<= 3;
- input[8] <<= 4;
- input[9] <<= 6;
-#define F(i, s) \
- output[s+0] |= input[i] & 0xff; \
- output[s+1] = (input[i] >> 8) & 0xff; \
- output[s+2] = (input[i] >> 16) & 0xff; \
- output[s+3] = (input[i] >> 24) & 0xff;
- output[0] = 0;
- output[16] = 0;
- F(0,0);
- F(1,3);
- F(2,6);
- F(3,9);
- F(4,12);
- F(5,16);
- F(6,19);
- F(7,22);
- F(8,25);
- F(9,28);
-#undef F
-}
-
-/* Input: Q, Q', Q-Q'
- * Output: 2Q, Q+Q'
- *
- * x2 z3: long form
- * x3 z3: long form
- * x z: short form, destroyed
- * xprime zprime: short form, destroyed
- * qmqp: short form, preserved
- */
-static void fmonty(felem *x2, felem *z2, /* output 2Q */
- felem *x3, felem *z3, /* output Q + Q' */
- felem *x, felem *z, /* input Q */
- felem *xprime, felem *zprime, /* input Q' */
- felem *qmqp /* input Q - Q' */) {
- felem origx[10], origxprime[10], zzz[19], xx[19], zz[19], xxprime[19],
- zzprime[19], zzzprime[19], xxxprime[19];
-
- memcpy(origx, x, 10 * sizeof(felem));
- fsum(x, z);
- fdifference(z, origx); // does x - z
-
- memcpy(origxprime, xprime, sizeof(felem) * 10);
- fsum(xprime, zprime);
- fdifference(zprime, origxprime);
- fproduct(xxprime, xprime, z);
- fproduct(zzprime, x, zprime);
- freduce_degree(xxprime);
- freduce_coefficients(xxprime);
- freduce_degree(zzprime);
- freduce_coefficients(zzprime);
- memcpy(origxprime, xxprime, sizeof(felem) * 10);
- fsum(xxprime, zzprime);
- fdifference(zzprime, origxprime);
- fsquare(xxxprime, xxprime);
- fsquare(zzzprime, zzprime);
- fproduct(zzprime, zzzprime, qmqp);
- freduce_degree(zzprime);
- freduce_coefficients(zzprime);
- memcpy(x3, xxxprime, sizeof(felem) * 10);
- memcpy(z3, zzprime, sizeof(felem) * 10);
-
- fsquare(xx, x);
- fsquare(zz, z);
- fproduct(x2, xx, zz);
- freduce_degree(x2);
- freduce_coefficients(x2);
- fdifference(zz, xx); // does zz = xx - zz
- memset(zzz + 10, 0, sizeof(felem) * 9);
- fscalar_product(zzz, zz, 121665);
- freduce_degree(zzz);
- freduce_coefficients(zzz);
- fsum(zzz, xx);
- fproduct(z2, zz, zzz);
- freduce_degree(z2);
- freduce_coefficients(z2);
-}
-
-/* Calculates nQ where Q is the x-coordinate of a point on the curve
- *
- * resultx/resultz: the x coordinate of the resulting curve point (short form)
- * n: a little endian, 32-byte number
- * q: a point of the curve (short form)
- */
-static void
-cmult(felem *resultx, felem *resultz, uchar *n, felem *q) {
- felem a[19] = {0}, b[19] = {1}, c[19] = {1}, d[19] = {0};
- felem *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t;
- felem e[19] = {0}, f[19] = {1}, g[19] = {0}, h[19] = {1};
- felem *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h;
-
- unsigned i, j;
-
- memcpy(nqpqx, q, sizeof(felem) * 10);
-
- for (i = 0; i < 32; ++i) {
- uchar byte = n[31 - i];
- for (j = 0; j < 8; ++j) {
- if (byte & 0x80) {
- fmonty(nqpqx2, nqpqz2,
- nqx2, nqz2,
- nqpqx, nqpqz,
- nqx, nqz,
- q);
- } else {
- fmonty(nqx2, nqz2,
- nqpqx2, nqpqz2,
- nqx, nqz,
- nqpqx, nqpqz,
- q);
- }
-
- t = nqx;
- nqx = nqx2;
- nqx2 = t;
- t = nqz;
- nqz = nqz2;
- nqz2 = t;
- t = nqpqx;
- nqpqx = nqpqx2;
- nqpqx2 = t;
- t = nqpqz;
- nqpqz = nqpqz2;
- nqpqz2 = t;
-
- byte <<= 1;
- }
- }
-
- memcpy(resultx, nqx, sizeof(felem) * 10);
- memcpy(resultz, nqz, sizeof(felem) * 10);
-}
-
-// -----------------------------------------------------------------------------
-// Shamelessly copied from djb's code
-// -----------------------------------------------------------------------------
-static void
-crecip(felem *out, felem *z) {
- felem z2[10];
- felem z9[10];
- felem z11[10];
- felem z2_5_0[10];
- felem z2_10_0[10];
- felem z2_20_0[10];
- felem z2_50_0[10];
- felem z2_100_0[10];
- felem t0[10];
- felem t1[10];
- int i;
-
- /* 2 */ fsquare(z2,z);
- /* 4 */ fsquare(t1,z2);
- /* 8 */ fsquare(t0,t1);
- /* 9 */ fmul(z9,t0,z);
- /* 11 */ fmul(z11,z9,z2);
- /* 22 */ fsquare(t0,z11);
- /* 2^5 - 2^0 = 31 */ fmul(z2_5_0,t0,z9);
-
- /* 2^6 - 2^1 */ fsquare(t0,z2_5_0);
- /* 2^7 - 2^2 */ fsquare(t1,t0);
- /* 2^8 - 2^3 */ fsquare(t0,t1);
- /* 2^9 - 2^4 */ fsquare(t1,t0);
- /* 2^10 - 2^5 */ fsquare(t0,t1);
- /* 2^10 - 2^0 */ fmul(z2_10_0,t0,z2_5_0);
-
- /* 2^11 - 2^1 */ fsquare(t0,z2_10_0);
- /* 2^12 - 2^2 */ fsquare(t1,t0);
- /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
- /* 2^20 - 2^0 */ fmul(z2_20_0,t1,z2_10_0);
-
- /* 2^21 - 2^1 */ fsquare(t0,z2_20_0);
- /* 2^22 - 2^2 */ fsquare(t1,t0);
- /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
- /* 2^40 - 2^0 */ fmul(t0,t1,z2_20_0);
-
- /* 2^41 - 2^1 */ fsquare(t1,t0);
- /* 2^42 - 2^2 */ fsquare(t0,t1);
- /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
- /* 2^50 - 2^0 */ fmul(z2_50_0,t0,z2_10_0);
-
- /* 2^51 - 2^1 */ fsquare(t0,z2_50_0);
- /* 2^52 - 2^2 */ fsquare(t1,t0);
- /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
- /* 2^100 - 2^0 */ fmul(z2_100_0,t1,z2_50_0);
-
- /* 2^101 - 2^1 */ fsquare(t1,z2_100_0);
- /* 2^102 - 2^2 */ fsquare(t0,t1);
- /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
- /* 2^200 - 2^0 */ fmul(t1,t0,z2_100_0);
-
- /* 2^201 - 2^1 */ fsquare(t0,t1);
- /* 2^202 - 2^2 */ fsquare(t1,t0);
- /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
- /* 2^250 - 2^0 */ fmul(t0,t1,z2_50_0);
-
- /* 2^251 - 2^1 */ fsquare(t1,t0);
- /* 2^252 - 2^2 */ fsquare(t0,t1);
- /* 2^253 - 2^3 */ fsquare(t1,t0);
- /* 2^254 - 2^4 */ fsquare(t0,t1);
- /* 2^255 - 2^5 */ fsquare(t1,t0);
- /* 2^255 - 21 */ fmul(out,t1,z11);
-}
-
-void
-curve25519(uchar mypublic[32], uchar secret[32], uchar basepoint[32]) {
- felem bp[10], x[10], z[10], zmone[10];
- fexpand(bp, basepoint);
- cmult(x, z, secret, bp);
- crecip(zmone, z);
- fmul(z, x, zmone);
- fcontract(mypublic, z);
-}
--- a/libsec/curve25519_dh.c
+++ /dev/null
@@ -1,37 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include <libsec.h>
-
-static uchar nine[32] = {9};
-static uchar zero[32] = {0};
-
-void
-curve25519_dh_new(uchar x[32], uchar y[32])
-{
- uchar b;
-
- /* new public/private key pair */
- genrandom(x, 32);
- b = x[31];
- x[0] &= ~7; /* clear bit 0,1,2 */
- x[31] = 0x40 | (b & 0x7f); /* set bit 254, clear bit 255 */
- curve25519(y, x, nine);
-
- /* bit 255 is always 0, so make it random */
- y[31] |= b & 0x80;
-}
-
-int
-curve25519_dh_finish(uchar x[32], uchar y[32], uchar z[32])
-{
- /* remove the random bit */
- y[31] &= 0x7f;
-
- /* calculate dhx key */
- curve25519(z, x, y);
-
- memset(x, 0, 32);
- memset(y, 0, 32);
-
- return tsmemcmp(z, zero, 32) != 0;
-}
--- a/libsec/decodepem.c
+++ /dev/null
@@ -1,89 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-#define STRLEN(s) (sizeof(s)-1)
-
-uchar*
-decodePEM(char *s, char *type, int *len, char **new_s)
-{
- uchar *d;
- char *t, *e, *tt;
- int n;
-
- *len = 0;
-
- /*
- * find the correct section of the file, stripping garbage at the beginning and end.
- * the data is delimited by -----BEGIN <type>-----\n and -----END <type>-----\n
- */
- n = strlen(type);
- e = strchr(s, '\0');
- for(t = s; t != nil && t < e; ){
- tt = t;
- t = strchr(tt, '\n');
- if(t != nil)
- t++;
- if(strncmp(tt, "-----BEGIN ", STRLEN("-----BEGIN ")) == 0
- && strncmp(&tt[STRLEN("-----BEGIN ")], type, n) == 0
- && strncmp(&tt[STRLEN("-----BEGIN ")+n], "-----", STRLEN("-----")) == 0
- && strchr("\r\n", tt[STRLEN("-----BEGIN ")+n+STRLEN("-----")]) != nil)
- break;
- }
- for(tt = t; tt != nil && tt < e; tt++){
- if(strncmp(tt, "-----END ", STRLEN("-----END ")) == 0
- && strncmp(&tt[STRLEN("-----END ")], type, n) == 0
- && strncmp(&tt[STRLEN("-----END ")+n], "-----", STRLEN("-----")) == 0
- && strchr("\r\n", tt[STRLEN("-----END ")+n+STRLEN("-----")]) != nil)
- break;
- tt = strchr(tt, '\n');
- if(tt == nil)
- break;
- }
- if(tt == nil || tt == e){
- werrstr("incorrect .pem file format: bad header or trailer");
- return nil;
- }
-
- if(new_s)
- *new_s = tt+1;
- n = ((tt - t) * 6 + 7) / 8;
- d = malloc(n);
- if(d == nil){
- werrstr("out of memory");
- return nil;
- }
- n = dec64(d, n, t, tt - t);
- if(n < 0){
- free(d);
- werrstr("incorrect .pem file format: bad base64 encoded data");
- return nil;
- }
- *len = n;
- return d;
-}
-
-PEMChain*
-decodepemchain(char *s, char *type)
-{
- PEMChain *first = nil, *last = nil, *chp;
- uchar *d;
- char *e;
- int n;
-
- e = strchr(s, '\0');
- while (s < e) {
- d = decodePEM(s, type, &n, &s);
- if(d == nil)
- break;
- chp = malloc(sizeof(PEMChain));
- chp->next = nil;
- chp->pem = d;
- chp->pemlen = n;
- if (first == nil)
- first = chp;
- else
- last->next = chp;
- last = chp;
- }
- return first;
-}
--- a/libsec/des.c
+++ /dev/null
@@ -1,480 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-/*
- * integrated sbox & p perm
- */
-static u32int spbox[] = {
-
-0x00808200,0x00000000,0x00008000,0x00808202,0x00808002,0x00008202,0x00000002,0x00008000,
-0x00000200,0x00808200,0x00808202,0x00000200,0x00800202,0x00808002,0x00800000,0x00000002,
-0x00000202,0x00800200,0x00800200,0x00008200,0x00008200,0x00808000,0x00808000,0x00800202,
-0x00008002,0x00800002,0x00800002,0x00008002,0x00000000,0x00000202,0x00008202,0x00800000,
-0x00008000,0x00808202,0x00000002,0x00808000,0x00808200,0x00800000,0x00800000,0x00000200,
-0x00808002,0x00008000,0x00008200,0x00800002,0x00000200,0x00000002,0x00800202,0x00008202,
-0x00808202,0x00008002,0x00808000,0x00800202,0x00800002,0x00000202,0x00008202,0x00808200,
-0x00000202,0x00800200,0x00800200,0x00000000,0x00008002,0x00008200,0x00000000,0x00808002,
-
-0x40084010,0x40004000,0x00004000,0x00084010,0x00080000,0x00000010,0x40080010,0x40004010,
-0x40000010,0x40084010,0x40084000,0x40000000,0x40004000,0x00080000,0x00000010,0x40080010,
-0x00084000,0x00080010,0x40004010,0x00000000,0x40000000,0x00004000,0x00084010,0x40080000,
-0x00080010,0x40000010,0x00000000,0x00084000,0x00004010,0x40084000,0x40080000,0x00004010,
-0x00000000,0x00084010,0x40080010,0x00080000,0x40004010,0x40080000,0x40084000,0x00004000,
-0x40080000,0x40004000,0x00000010,0x40084010,0x00084010,0x00000010,0x00004000,0x40000000,
-0x00004010,0x40084000,0x00080000,0x40000010,0x00080010,0x40004010,0x40000010,0x00080010,
-0x00084000,0x00000000,0x40004000,0x00004010,0x40000000,0x40080010,0x40084010,0x00084000,
-
-0x00000104,0x04010100,0x00000000,0x04010004,0x04000100,0x00000000,0x00010104,0x04000100,
-0x00010004,0x04000004,0x04000004,0x00010000,0x04010104,0x00010004,0x04010000,0x00000104,
-0x04000000,0x00000004,0x04010100,0x00000100,0x00010100,0x04010000,0x04010004,0x00010104,
-0x04000104,0x00010100,0x00010000,0x04000104,0x00000004,0x04010104,0x00000100,0x04000000,
-0x04010100,0x04000000,0x00010004,0x00000104,0x00010000,0x04010100,0x04000100,0x00000000,
-0x00000100,0x00010004,0x04010104,0x04000100,0x04000004,0x00000100,0x00000000,0x04010004,
-0x04000104,0x00010000,0x04000000,0x04010104,0x00000004,0x00010104,0x00010100,0x04000004,
-0x04010000,0x04000104,0x00000104,0x04010000,0x00010104,0x00000004,0x04010004,0x00010100,
-
-0x80401000,0x80001040,0x80001040,0x00000040,0x00401040,0x80400040,0x80400000,0x80001000,
-0x00000000,0x00401000,0x00401000,0x80401040,0x80000040,0x00000000,0x00400040,0x80400000,
-0x80000000,0x00001000,0x00400000,0x80401000,0x00000040,0x00400000,0x80001000,0x00001040,
-0x80400040,0x80000000,0x00001040,0x00400040,0x00001000,0x00401040,0x80401040,0x80000040,
-0x00400040,0x80400000,0x00401000,0x80401040,0x80000040,0x00000000,0x00000000,0x00401000,
-0x00001040,0x00400040,0x80400040,0x80000000,0x80401000,0x80001040,0x80001040,0x00000040,
-0x80401040,0x80000040,0x80000000,0x00001000,0x80400000,0x80001000,0x00401040,0x80400040,
-0x80001000,0x00001040,0x00400000,0x80401000,0x00000040,0x00400000,0x00001000,0x00401040,
-
-0x00000080,0x01040080,0x01040000,0x21000080,0x00040000,0x00000080,0x20000000,0x01040000,
-0x20040080,0x00040000,0x01000080,0x20040080,0x21000080,0x21040000,0x00040080,0x20000000,
-0x01000000,0x20040000,0x20040000,0x00000000,0x20000080,0x21040080,0x21040080,0x01000080,
-0x21040000,0x20000080,0x00000000,0x21000000,0x01040080,0x01000000,0x21000000,0x00040080,
-0x00040000,0x21000080,0x00000080,0x01000000,0x20000000,0x01040000,0x21000080,0x20040080,
-0x01000080,0x20000000,0x21040000,0x01040080,0x20040080,0x00000080,0x01000000,0x21040000,
-0x21040080,0x00040080,0x21000000,0x21040080,0x01040000,0x00000000,0x20040000,0x21000000,
-0x00040080,0x01000080,0x20000080,0x00040000,0x00000000,0x20040000,0x01040080,0x20000080,
-
-0x10000008,0x10200000,0x00002000,0x10202008,0x10200000,0x00000008,0x10202008,0x00200000,
-0x10002000,0x00202008,0x00200000,0x10000008,0x00200008,0x10002000,0x10000000,0x00002008,
-0x00000000,0x00200008,0x10002008,0x00002000,0x00202000,0x10002008,0x00000008,0x10200008,
-0x10200008,0x00000000,0x00202008,0x10202000,0x00002008,0x00202000,0x10202000,0x10000000,
-0x10002000,0x00000008,0x10200008,0x00202000,0x10202008,0x00200000,0x00002008,0x10000008,
-0x00200000,0x10002000,0x10000000,0x00002008,0x10000008,0x10202008,0x00202000,0x10200000,
-0x00202008,0x10202000,0x00000000,0x10200008,0x00000008,0x00002000,0x10200000,0x00202008,
-0x00002000,0x00200008,0x10002008,0x00000000,0x10202000,0x10000000,0x00200008,0x10002008,
-
-0x00100000,0x02100001,0x02000401,0x00000000,0x00000400,0x02000401,0x00100401,0x02100400,
-0x02100401,0x00100000,0x00000000,0x02000001,0x00000001,0x02000000,0x02100001,0x00000401,
-0x02000400,0x00100401,0x00100001,0x02000400,0x02000001,0x02100000,0x02100400,0x00100001,
-0x02100000,0x00000400,0x00000401,0x02100401,0x00100400,0x00000001,0x02000000,0x00100400,
-0x02000000,0x00100400,0x00100000,0x02000401,0x02000401,0x02100001,0x02100001,0x00000001,
-0x00100001,0x02000000,0x02000400,0x00100000,0x02100400,0x00000401,0x00100401,0x02100400,
-0x00000401,0x02000001,0x02100401,0x02100000,0x00100400,0x00000000,0x00000001,0x02100401,
-0x00000000,0x00100401,0x02100000,0x00000400,0x02000001,0x02000400,0x00000400,0x00100001,
-
-0x08000820,0x00000800,0x00020000,0x08020820,0x08000000,0x08000820,0x00000020,0x08000000,
-0x00020020,0x08020000,0x08020820,0x00020800,0x08020800,0x00020820,0x00000800,0x00000020,
-0x08020000,0x08000020,0x08000800,0x00000820,0x00020800,0x00020020,0x08020020,0x08020800,
-0x00000820,0x00000000,0x00000000,0x08020020,0x08000020,0x08000800,0x00020820,0x00020000,
-0x00020820,0x00020000,0x08020800,0x00000800,0x00000020,0x08020020,0x00000800,0x00020820,
-0x08000800,0x00000020,0x08000020,0x08020000,0x08020020,0x08000000,0x00020000,0x08000820,
-0x00000000,0x08020820,0x00020020,0x08000020,0x08020000,0x08000800,0x08000820,0x00000000,
-0x08020820,0x00020800,0x00020800,0x00000820,0x00000820,0x00020020,0x08000000,0x08020800,
-};
-
-/*
- * for manual index calculation
- * #define fetch(box, i, sh) (*((u32int*)((uchar*)spbox + (box << 8) + ((i >> (sh)) & 0xfc))))
- */
-#define fetch(box, i, sh) ((spbox+(box << 6))[((i >> (sh + 2)) & 0x3f)])
-
-/*
- * DES electronic codebook encryption of one block
- */
-void
-block_cipher(ulong key[32], uchar text[8], int decrypting)
-{
- u32int right, left, v0, v1;
- int i, keystep;
-
- /*
- * initial permutation
- */
- v0 = text[0] | ((u32int)text[2]<<8) | ((u32int)text[4]<<16) | ((u32int)text[6]<<24);
- left = text[1] | ((u32int)text[3]<<8) | ((u32int)text[5]<<16) | ((u32int)text[7]<<24);
- right = (left & 0xaaaaaaaa) | ((v0 >> 1) & 0x55555555);
- left = ((left << 1) & 0xaaaaaaaa) | (v0 & 0x55555555);
- left = ((left << 6) & 0x33003300)
- | (left & 0xcc33cc33)
- | ((left >> 6) & 0x00cc00cc);
- left = ((left << 12) & 0x0f0f0000)
- | (left & 0xf0f00f0f)
- | ((left >> 12) & 0x0000f0f0);
- right = ((right << 6) & 0x33003300)
- | (right & 0xcc33cc33)
- | ((right >> 6) & 0x00cc00cc);
- right = ((right << 12) & 0x0f0f0000)
- | (right & 0xf0f00f0f)
- | ((right >> 12) & 0x0000f0f0);
-
- if (decrypting) {
- keystep = -2;
- key = key + 32 - 2;
- } else
- keystep = 2;
- for (i = 0; i < 8; i++) {
- v0 = key[0];
- v0 ^= (right >> 1) | (right << 31);
- left ^= fetch(0, v0, 24)
- ^ fetch(2, v0, 16)
- ^ fetch(4, v0, 8)
- ^ fetch(6, v0, 0);
- v1 = key[1];
- v1 ^= (right << 3) | (right >> 29);
- left ^= fetch(1, v1, 24)
- ^ fetch(3, v1, 16)
- ^ fetch(5, v1, 8)
- ^ fetch(7, v1, 0);
- key += keystep;
-
- v0 = key[0];
- v0 ^= (left >> 1) | (left << 31);
- right ^= fetch(0, v0, 24)
- ^ fetch(2, v0, 16)
- ^ fetch(4, v0, 8)
- ^ fetch(6, v0, 0);
- v1 = key[1];
- v1 ^= (left << 3) | (left >> 29);
- right ^= fetch(1, v1, 24)
- ^ fetch(3, v1, 16)
- ^ fetch(5, v1, 8)
- ^ fetch(7, v1, 0);
- key += keystep;
- }
-
- /*
- * final permutation, inverse initial permutation
- */
- v0 = ((left << 1) & 0xaaaaaaaa) | (right & 0x55555555);
- v1 = (left & 0xaaaaaaaa) | ((right >> 1) & 0x55555555);
- v1 = ((v1 << 6) & 0x33003300)
- | (v1 & 0xcc33cc33)
- | ((v1 >> 6) & 0x00cc00cc);
- v1 = ((v1 << 12) & 0x0f0f0000)
- | (v1 & 0xf0f00f0f)
- | ((v1 >> 12) & 0x0000f0f0);
- v0 = ((v0 << 6) & 0x33003300)
- | (v0 & 0xcc33cc33)
- | ((v0 >> 6) & 0x00cc00cc);
- v0 = ((v0 << 12) & 0x0f0f0000)
- | (v0 & 0xf0f00f0f)
- | ((v0 >> 12) & 0x0000f0f0);
- text[0] = v0;
- text[2] = v0 >> 8;
- text[4] = v0 >> 16;
- text[6] = v0 >> 24;
- text[1] = v1;
- text[3] = v1 >> 8;
- text[5] = v1 >> 16;
- text[7] = v1 >> 24;
-}
-
-/*
- * triple DES electronic codebook encryption of one block
- */
-void
-triple_block_cipher(ulong expanded_key[3][32], uchar text[8], int ende)
-{
- ulong *key;
- u32int right, left, v0, v1;
- int i, j, keystep;
-
- /*
- * initial permutation
- */
- v0 = text[0] | ((u32int)text[2]<<8) | ((u32int)text[4]<<16) | ((u32int)text[6]<<24);
- left = text[1] | ((u32int)text[3]<<8) | ((u32int)text[5]<<16) | ((u32int)text[7]<<24);
- right = (left & 0xaaaaaaaa) | ((v0 >> 1) & 0x55555555);
- left = ((left << 1) & 0xaaaaaaaa) | (v0 & 0x55555555);
- left = ((left << 6) & 0x33003300)
- | (left & 0xcc33cc33)
- | ((left >> 6) & 0x00cc00cc);
- left = ((left << 12) & 0x0f0f0000)
- | (left & 0xf0f00f0f)
- | ((left >> 12) & 0x0000f0f0);
- right = ((right << 6) & 0x33003300)
- | (right & 0xcc33cc33)
- | ((right >> 6) & 0x00cc00cc);
- right = ((right << 12) & 0x0f0f0000)
- | (right & 0xf0f00f0f)
- | ((right >> 12) & 0x0000f0f0);
-
- for(j = 0; j < 3; j++){
- if((ende & 1) == DES3D) {
- key = &expanded_key[2-j][32-2];
- keystep = -2;
- } else {
- key = &expanded_key[j][0];
- keystep = 2;
- }
- ende >>= 1;
- for (i = 0; i < 8; i++) {
- v0 = key[0];
- v0 ^= (right >> 1) | (right << 31);
- left ^= fetch(0, v0, 24)
- ^ fetch(2, v0, 16)
- ^ fetch(4, v0, 8)
- ^ fetch(6, v0, 0);
- v1 = key[1];
- v1 ^= (right << 3) | (right >> 29);
- left ^= fetch(1, v1, 24)
- ^ fetch(3, v1, 16)
- ^ fetch(5, v1, 8)
- ^ fetch(7, v1, 0);
- key += keystep;
-
- v0 = key[0];
- v0 ^= (left >> 1) | (left << 31);
- right ^= fetch(0, v0, 24)
- ^ fetch(2, v0, 16)
- ^ fetch(4, v0, 8)
- ^ fetch(6, v0, 0);
- v1 = key[1];
- v1 ^= (left << 3) | (left >> 29);
- right ^= fetch(1, v1, 24)
- ^ fetch(3, v1, 16)
- ^ fetch(5, v1, 8)
- ^ fetch(7, v1, 0);
- key += keystep;
- }
-
- v0 = left;
- left = right;
- right = v0;
- }
-
- /*
- * final permutation, inverse initial permutation
- * left and right are swapped here
- */
- v0 = ((right << 1) & 0xaaaaaaaa) | (left & 0x55555555);
- v1 = (right & 0xaaaaaaaa) | ((left >> 1) & 0x55555555);
- v1 = ((v1 << 6) & 0x33003300)
- | (v1 & 0xcc33cc33)
- | ((v1 >> 6) & 0x00cc00cc);
- v1 = ((v1 << 12) & 0x0f0f0000)
- | (v1 & 0xf0f00f0f)
- | ((v1 >> 12) & 0x0000f0f0);
- v0 = ((v0 << 6) & 0x33003300)
- | (v0 & 0xcc33cc33)
- | ((v0 >> 6) & 0x00cc00cc);
- v0 = ((v0 << 12) & 0x0f0f0000)
- | (v0 & 0xf0f00f0f)
- | ((v0 >> 12) & 0x0000f0f0);
- text[0] = v0;
- text[2] = v0 >> 8;
- text[4] = v0 >> 16;
- text[6] = v0 >> 24;
- text[1] = v1;
- text[3] = v1 >> 8;
- text[5] = v1 >> 16;
- text[7] = v1 >> 24;
-}
-
-/*
- * key compression permutation, 4 bits at a time
- */
-static u32int comptab[] = {
-
-0x000000,0x010000,0x000008,0x010008,0x000080,0x010080,0x000088,0x010088,
-0x000000,0x010000,0x000008,0x010008,0x000080,0x010080,0x000088,0x010088,
-
-0x000000,0x100000,0x000800,0x100800,0x000000,0x100000,0x000800,0x100800,
-0x002000,0x102000,0x002800,0x102800,0x002000,0x102000,0x002800,0x102800,
-
-0x000000,0x000004,0x000400,0x000404,0x000000,0x000004,0x000400,0x000404,
-0x400000,0x400004,0x400400,0x400404,0x400000,0x400004,0x400400,0x400404,
-
-0x000000,0x000020,0x008000,0x008020,0x800000,0x800020,0x808000,0x808020,
-0x000002,0x000022,0x008002,0x008022,0x800002,0x800022,0x808002,0x808022,
-
-0x000000,0x000200,0x200000,0x200200,0x001000,0x001200,0x201000,0x201200,
-0x000000,0x000200,0x200000,0x200200,0x001000,0x001200,0x201000,0x201200,
-
-0x000000,0x000040,0x000010,0x000050,0x004000,0x004040,0x004010,0x004050,
-0x040000,0x040040,0x040010,0x040050,0x044000,0x044040,0x044010,0x044050,
-
-0x000000,0x000100,0x020000,0x020100,0x000001,0x000101,0x020001,0x020101,
-0x080000,0x080100,0x0a0000,0x0a0100,0x080001,0x080101,0x0a0001,0x0a0101,
-
-0x000000,0x000100,0x040000,0x040100,0x000000,0x000100,0x040000,0x040100,
-0x000040,0x000140,0x040040,0x040140,0x000040,0x000140,0x040040,0x040140,
-
-0x000000,0x400000,0x008000,0x408000,0x000008,0x400008,0x008008,0x408008,
-0x000400,0x400400,0x008400,0x408400,0x000408,0x400408,0x008408,0x408408,
-
-0x000000,0x001000,0x080000,0x081000,0x000020,0x001020,0x080020,0x081020,
-0x004000,0x005000,0x084000,0x085000,0x004020,0x005020,0x084020,0x085020,
-
-0x000000,0x000800,0x000000,0x000800,0x000010,0x000810,0x000010,0x000810,
-0x800000,0x800800,0x800000,0x800800,0x800010,0x800810,0x800010,0x800810,
-
-0x000000,0x010000,0x000200,0x010200,0x000000,0x010000,0x000200,0x010200,
-0x100000,0x110000,0x100200,0x110200,0x100000,0x110000,0x100200,0x110200,
-
-0x000000,0x000004,0x000000,0x000004,0x000080,0x000084,0x000080,0x000084,
-0x002000,0x002004,0x002000,0x002004,0x002080,0x002084,0x002080,0x002084,
-
-0x000000,0x000001,0x200000,0x200001,0x020000,0x020001,0x220000,0x220001,
-0x000002,0x000003,0x200002,0x200003,0x020002,0x020003,0x220002,0x220003,
-};
-
-static int keysh[] =
-{
- 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
-};
-
-static void
-keycompperm(u32int left, u32int right, ulong *ek)
-{
- u32int v0, v1;
- int i;
-
- for(i = 0; i < 16; i++){
- left = (left << keysh[i]) | (left >> (28 - keysh[i]));
- left &= 0xfffffff0;
- right = (right << keysh[i]) | (right >> (28 - keysh[i]));
- right &= 0xfffffff0;
- v0 = comptab[6 * (1 << 4) + ((left >> (32-4)) & 0xf)]
- | comptab[5 * (1 << 4) + ((left >> (32-8)) & 0xf)]
- | comptab[4 * (1 << 4) + ((left >> (32-12)) & 0xf)]
- | comptab[3 * (1 << 4) + ((left >> (32-16)) & 0xf)]
- | comptab[2 * (1 << 4) + ((left >> (32-20)) & 0xf)]
- | comptab[1 * (1 << 4) + ((left >> (32-24)) & 0xf)]
- | comptab[0 * (1 << 4) + ((left >> (32-28)) & 0xf)];
- v1 = comptab[13 * (1 << 4) + ((right >> (32-4)) & 0xf)]
- | comptab[12 * (1 << 4) + ((right >> (32-8)) & 0xf)]
- | comptab[11 * (1 << 4) + ((right >> (32-12)) & 0xf)]
- | comptab[10 * (1 << 4) + ((right >> (32-16)) & 0xf)]
- | comptab[9 * (1 << 4) + ((right >> (32-20)) & 0xf)]
- | comptab[8 * (1 << 4) + ((right >> (32-24)) & 0xf)]
- | comptab[7 * (1 << 4) + ((right >> (32-28)) & 0xf)];
- ek[0] = (((v0 >> (24-6)) & 0x3f) << 26)
- | (((v0 >> (24-18)) & 0x3f) << 18)
- | (((v1 >> (24-6)) & 0x3f) << 10)
- | (((v1 >> (24-18)) & 0x3f) << 2);
- ek[1] = (((v0 >> (24-12)) & 0x3f) << 26)
- | (((v0 >> (24-24)) & 0x3f) << 18)
- | (((v1 >> (24-12)) & 0x3f) << 10)
- | (((v1 >> (24-24)) & 0x3f) << 2);
- ek += 2;
- }
-}
-
-void
-des_key_setup(uchar key[8], ulong ek[32])
-{
- u32int left, right, v0, v1;
-
- v0 = key[0] | ((u32int)key[2] << 8) | ((u32int)key[4] << 16) | ((u32int)key[6] << 24);
- v1 = key[1] | ((u32int)key[3] << 8) | ((u32int)key[5] << 16) | ((u32int)key[7] << 24);
- left = ((v0 >> 1) & 0x40404040)
- | ((v0 >> 2) & 0x10101010)
- | ((v0 >> 3) & 0x04040404)
- | ((v0 >> 4) & 0x01010101)
- | ((v1 >> 0) & 0x80808080)
- | ((v1 >> 1) & 0x20202020)
- | ((v1 >> 2) & 0x08080808)
- | ((v1 >> 3) & 0x02020202);
- right = ((v0 >> 1) & 0x04040404)
- | ((v0 << 2) & 0x10101010)
- | ((v0 << 5) & 0x40404040)
- | ((v1 << 0) & 0x08080808)
- | ((v1 << 3) & 0x20202020)
- | ((v1 << 6) & 0x80808080);
- left = ((left << 6) & 0x33003300)
- | (left & 0xcc33cc33)
- | ((left >> 6) & 0x00cc00cc);
- v0 = ((left << 12) & 0x0f0f0000)
- | (left & 0xf0f00f0f)
- | ((left >> 12) & 0x0000f0f0);
- right = ((right << 6) & 0x33003300)
- | (right & 0xcc33cc33)
- | ((right >> 6) & 0x00cc00cc);
- v1 = ((right << 12) & 0x0f0f0000)
- | (right & 0xf0f00f0f)
- | ((right >> 12) & 0x0000f0f0);
- left = v0 & 0xfffffff0;
- right = (v1 & 0xffffff00) | ((v0 << 4) & 0xf0);
-
- keycompperm(left, right, ek);
-}
-
-static uchar parity[128] =
-{
- 0x01, 0x02, 0x04, 0x07, 0x08, 0x0b, 0x0d, 0x0e,
- 0x10, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c, 0x1f,
- 0x20, 0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x2f,
- 0x31, 0x32, 0x34, 0x37, 0x38, 0x3b, 0x3d, 0x3e,
- 0x40, 0x43, 0x45, 0x46, 0x49, 0x4a, 0x4c, 0x4f,
- 0x51, 0x52, 0x54, 0x57, 0x58, 0x5b, 0x5d, 0x5e,
- 0x61, 0x62, 0x64, 0x67, 0x68, 0x6b, 0x6d, 0x6e,
- 0x70, 0x73, 0x75, 0x76, 0x79, 0x7a, 0x7c, 0x7f,
- 0x80, 0x83, 0x85, 0x86, 0x89, 0x8a, 0x8c, 0x8f,
- 0x91, 0x92, 0x94, 0x97, 0x98, 0x9b, 0x9d, 0x9e,
- 0xa1, 0xa2, 0xa4, 0xa7, 0xa8, 0xab, 0xad, 0xae,
- 0xb0, 0xb3, 0xb5, 0xb6, 0xb9, 0xba, 0xbc, 0xbf,
- 0xc1, 0xc2, 0xc4, 0xc7, 0xc8, 0xcb, 0xcd, 0xce,
- 0xd0, 0xd3, 0xd5, 0xd6, 0xd9, 0xda, 0xdc, 0xdf,
- 0xe0, 0xe3, 0xe5, 0xe6, 0xe9, 0xea, 0xec, 0xef,
- 0xf1, 0xf2, 0xf4, 0xf7, 0xf8, 0xfb, 0xfd, 0xfe,
-};
-
-/*
- * convert a 7 byte key to an 8 byte one
- */
-void
-des56to64(uchar *k56, uchar *k64)
-{
- u32int hi, lo;
-
- hi = ((u32int)k56[0]<<24)|((u32int)k56[1]<<16)|((u32int)k56[2]<<8)|k56[3];
- lo = ((u32int)k56[4]<<24)|((u32int)k56[5]<<16)|((u32int)k56[6]<<8);
-
- k64[0] = parity[(hi>>25)&0x7f];
- k64[1] = parity[(hi>>18)&0x7f];
- k64[2] = parity[(hi>>11)&0x7f];
- k64[3] = parity[(hi>>4)&0x7f];
- k64[4] = parity[((hi<<3)|(lo>>29))&0x7f];
- k64[5] = parity[(lo>>22)&0x7f];
- k64[6] = parity[(lo>>15)&0x7f];
- k64[7] = parity[(lo>>8)&0x7f];
-}
-
-/*
- * convert an 8 byte key to a 7 byte one
- */
-void
-des64to56(uchar *k64, uchar *k56)
-{
- u32int hi, lo;
-
- hi = (((u32int)k64[0]&0xfe)<<24)|(((u32int)k64[1]&0xfe)<<17)|(((u32int)k64[2]&0xfe)<<10)
- |((k64[3]&0xfe)<<3)|(k64[4]>>4);
- lo = (((u32int)k64[4]&0xfe)<<28)|(((u32int)k64[5]&0xfe)<<21)|(((u32int)k64[6]&0xfe)<<14)
- |(((u32int)k64[7]&0xfe)<<7);
-
- k56[0] = hi>>24;
- k56[1] = hi>>16;
- k56[2] = hi>>8;
- k56[3] = hi>>0;
- k56[4] = lo>>24;
- k56[5] = lo>>16;
- k56[6] = lo>>8;
-}
-
-void
-key_setup(uchar key[7], ulong ek[32])
-{
- uchar k64[8];
-
- des56to64(key, k64);
- des_key_setup(k64, ek);
-}
--- a/libsec/des3CBC.c
+++ /dev/null
@@ -1,58 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-// Because of the way that non multiple of 8
-// buffers are handled, the decryptor must
-// be fed buffers of the same size as the
-// encryptor
-
-
-// If the length is not a multiple of 8, I encrypt
-// the overflow to be compatible with lacy's cryptlib
-void
-des3CBCencrypt(uchar *p, int len, DES3state *s)
-{
- uchar *p2, *ip, *eip;
-
- for(; len >= 8; len -= 8){
- p2 = p;
- ip = s->ivec;
- for(eip = ip+8; ip < eip; )
- *p2++ ^= *ip++;
- triple_block_cipher(s->expanded, p, DES3EDE);
- memmove(s->ivec, p, 8);
- p += 8;
- }
-
- if(len > 0){
- ip = s->ivec;
- triple_block_cipher(s->expanded, ip, DES3EDE);
- for(eip = ip+len; ip < eip; )
- *p++ ^= *ip++;
- }
-}
-
-void
-des3CBCdecrypt(uchar *p, int len, DES3state *s)
-{
- uchar *ip, *eip, *tp;
- uchar tmp[8];
-
- for(; len >= 8; len -= 8){
- memmove(tmp, p, 8);
- triple_block_cipher(s->expanded, p, DES3DED);
- tp = tmp;
- ip = s->ivec;
- for(eip = ip+8; ip < eip; ){
- *p++ ^= *ip;
- *ip++ = *tp++;
- }
- }
-
- if(len > 0){
- ip = s->ivec;
- triple_block_cipher(s->expanded, ip, DES3EDE);
- for(eip = ip+len; ip < eip; )
- *p++ ^= *ip++;
- }
-}
--- a/libsec/desmodes.c
+++ /dev/null
@@ -1,31 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-/*
- * these routines use the 64bit format for
- * DES keys.
- */
-
-void
-setupDESstate(DESstate *s, uchar key[8], uchar *ivec)
-{
- memset(s, 0, sizeof(*s));
- memmove(s->key, key, sizeof(s->key));
- des_key_setup(key, s->expanded);
- if(ivec)
- memmove(s->ivec, ivec, 8);
- s->setup = 0xdeadbeef;
-}
-
-void
-setupDES3state(DES3state *s, uchar key[3][8], uchar *ivec)
-{
- memset(s, 0, sizeof(*s));
- memmove(s->key, key, sizeof(s->key));
- des_key_setup(key[0], s->expanded[0]);
- des_key_setup(key[1], s->expanded[1]);
- des_key_setup(key[2], s->expanded[2]);
- if(ivec)
- memmove(s->ivec, ivec, 8);
- s->setup = 0xdeadbeef;
-}
--- a/libsec/dh.c
+++ /dev/null
@@ -1,74 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include <libsec.h>
-
-mpint*
-dh_new(DHstate *dh, mpint *p, mpint *q, mpint *g)
-{
- mpint *pm1;
- int n;
-
- memset(dh, 0, sizeof(*dh));
- if(mpcmp(g, mpone) <= 0)
- return nil;
-
- n = mpsignif(p);
- pm1 = mpnew(n);
- mpsub(p, mpone, pm1);
- dh->p = mpcopy(p);
- dh->g = mpcopy(g);
- dh->q = mpcopy(q != nil ? q : pm1);
- dh->x = mpnew(mpsignif(dh->q));
- dh->y = mpnew(n);
- for(;;){
- mpnrand(dh->q, genrandom, dh->x);
- mpexp(dh->g, dh->x, dh->p, dh->y);
- if(mpcmp(dh->y, mpone) > 0 && mpcmp(dh->y, pm1) < 0)
- break;
- }
- mpfree(pm1);
-
- return dh->y;
-}
-
-mpint*
-dh_finish(DHstate *dh, mpint *y)
-{
- mpint *k = nil;
-
- if(y == nil || dh->x == nil || dh->p == nil || dh->q == nil)
- goto Out;
-
- /* y > 1 */
- if(mpcmp(y, mpone) <= 0)
- goto Out;
-
- k = mpnew(mpsignif(dh->p));
-
- /* y < p-1 */
- mpsub(dh->p, mpone, k);
- if(mpcmp(y, k) >= 0){
-Bad:
- mpfree(k);
- k = nil;
- goto Out;
- }
-
- /* y**q % p == 1 if q < p-1 */
- if(mpcmp(dh->q, k) < 0){
- mpexp(y, dh->q, dh->p, k);
- if(mpcmp(k, mpone) != 0)
- goto Bad;
- }
-
- mpexp(y, dh->x, dh->p, k);
-
-Out:
- mpfree(dh->p);
- mpfree(dh->q);
- mpfree(dh->g);
- mpfree(dh->x);
- mpfree(dh->y);
- memset(dh, 0, sizeof(*dh));
- return k;
-}
--- a/libsec/ecc.c
+++ /dev/null
@@ -1,612 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include <libsec.h>
-#include <ctype.h>
-
-extern void jacobian_affine(mpint *p,
- mpint *X, mpint *Y, mpint *Z);
-extern void jacobian_dbl(mpint *p, mpint *a,
- mpint *X1, mpint *Y1, mpint *Z1,
- mpint *X3, mpint *Y3, mpint *Z3);
-extern void jacobian_add(mpint *p, mpint *a,
- mpint *X1, mpint *Y1, mpint *Z1,
- mpint *X2, mpint *Y2, mpint *Z2,
- mpint *X3, mpint *Y3, mpint *Z3);
-
-void
-ecassign(ECdomain *dom, ECpoint *a, ECpoint *b)
-{
- if((b->inf = a->inf) != 0)
- return;
- mpassign(a->x, b->x);
- mpassign(a->y, b->y);
- if(b->z != nil){
- mpassign(a->z != nil ? a->z : mpone, b->z);
- return;
- }
- if(a->z != nil){
- b->z = mpcopy(a->z);
- jacobian_affine(dom->p, b->x, b->y, b->z);
- mpfree(b->z);
- b->z = nil;
- }
-}
-
-void
-ecadd(ECdomain *dom, ECpoint *a, ECpoint *b, ECpoint *s)
-{
- if(a->inf && b->inf){
- s->inf = 1;
- return;
- }
- if(a->inf){
- ecassign(dom, b, s);
- return;
- }
- if(b->inf){
- ecassign(dom, a, s);
- return;
- }
-
- if(s->z == nil){
- s->z = mpcopy(mpone);
- ecadd(dom, a, b, s);
- if(!s->inf)
- jacobian_affine(dom->p, s->x, s->y, s->z);
- mpfree(s->z);
- s->z = nil;
- return;
- }
-
- if(a == b)
- jacobian_dbl(dom->p, dom->a,
- a->x, a->y, a->z != nil ? a->z : mpone,
- s->x, s->y, s->z);
- else
- jacobian_add(dom->p, dom->a,
- a->x, a->y, a->z != nil ? a->z : mpone,
- b->x, b->y, b->z != nil ? b->z : mpone,
- s->x, s->y, s->z);
- s->inf = mpcmp(s->z, mpzero) == 0;
-}
-
-void
-ecmul(ECdomain *dom, ECpoint *a, mpint *k, ECpoint *s)
-{
- ECpoint ns, na;
- mpint *l;
-
- if(a->inf || mpcmp(k, mpzero) == 0){
- s->inf = 1;
- return;
- }
- ns.inf = 1;
- ns.x = mpnew(0);
- ns.y = mpnew(0);
- ns.z = mpnew(0);
- na.x = mpnew(0);
- na.y = mpnew(0);
- na.z = mpnew(0);
- ecassign(dom, a, &na);
- l = mpcopy(k);
- l->sign = 1;
- while(mpcmp(l, mpzero) != 0){
- if(l->p[0] & 1)
- ecadd(dom, &na, &ns, &ns);
- ecadd(dom, &na, &na, &na);
- mpright(l, 1, l);
- }
- if(k->sign < 0 && !ns.inf){
- ns.y->sign = -1;
- mpmod(ns.y, dom->p, ns.y);
- }
- ecassign(dom, &ns, s);
- mpfree(ns.x);
- mpfree(ns.y);
- mpfree(ns.z);
- mpfree(na.x);
- mpfree(na.y);
- mpfree(na.z);
- mpfree(l);
-}
-
-int
-ecverify(ECdomain *dom, ECpoint *a)
-{
- mpint *p, *q;
- int r;
-
- if(a->inf)
- return 1;
-
- assert(a->z == nil); /* need affine coordinates */
- p = mpnew(0);
- q = mpnew(0);
- mpmodmul(a->y, a->y, dom->p, p);
- mpmodmul(a->x, a->x, dom->p, q);
- mpmodadd(q, dom->a, dom->p, q);
- mpmodmul(q, a->x, dom->p, q);
- mpmodadd(q, dom->b, dom->p, q);
- r = mpcmp(p, q);
- mpfree(p);
- mpfree(q);
- return r == 0;
-}
-
-int
-ecpubverify(ECdomain *dom, ECpub *a)
-{
- ECpoint p;
- int r;
-
- if(a->inf)
- return 0;
- if(!ecverify(dom, a))
- return 0;
- p.x = mpnew(0);
- p.y = mpnew(0);
- p.z = mpnew(0);
- ecmul(dom, a, dom->n, &p);
- r = p.inf;
- mpfree(p.x);
- mpfree(p.y);
- mpfree(p.z);
- return r;
-}
-
-static void
-fixnibble(uchar *a)
-{
- if(*a >= 'a')
- *a -= 'a'-10;
- else if(*a >= 'A')
- *a -= 'A'-10;
- else
- *a -= '0';
-}
-
-static int
-octet(char **s)
-{
- uchar c, d;
-
- c = *(*s)++;
- if(!isxdigit(c))
- return -1;
- d = *(*s)++;
- if(!isxdigit(d))
- return -1;
- fixnibble(&c);
- fixnibble(&d);
- return (c << 4) | d;
-}
-
-static mpint*
-halfpt(ECdomain *dom, char *s, char **rptr, mpint *out)
-{
- char *buf, *r;
- int n;
- mpint *ret;
-
- n = ((mpsignif(dom->p)+7)/8)*2;
- if(strlen(s) < n)
- return 0;
- buf = malloc(n+1);
- buf[n] = 0;
- memcpy(buf, s, n);
- ret = strtomp(buf, &r, 16, out);
- *rptr = s + (r - buf);
- free(buf);
- return ret;
-}
-
-static int
-mpleg(mpint *a, mpint *b)
-{
- int r, k;
- mpint *m, *n, *t;
-
- r = 1;
- m = mpcopy(a);
- n = mpcopy(b);
- for(;;){
- if(mpcmp(m, n) > 0)
- mpmod(m, n, m);
- if(mpcmp(m, mpzero) == 0){
- r = 0;
- break;
- }
- if(mpcmp(m, mpone) == 0)
- break;
- k = mplowbits0(m);
- if(k > 0){
- if(k & 1)
- switch(n->p[0] & 15){
- case 3: case 5: case 11: case 13:
- r = -r;
- }
- mpright(m, k, m);
- }
- if((n->p[0] & 3) == 3 && (m->p[0] & 3) == 3)
- r = -r;
- t = m;
- m = n;
- n = t;
- }
- mpfree(m);
- mpfree(n);
- return r;
-}
-
-static int
-mpsqrt(mpint *n, mpint *p, mpint *r)
-{
- mpint *a, *t, *s, *xp, *xq, *yp, *yq, *zp, *zq, *N;
-
- if(mpleg(n, p) == -1)
- return 0;
- a = mpnew(0);
- t = mpnew(0);
- s = mpnew(0);
- N = mpnew(0);
- xp = mpnew(0);
- xq = mpnew(0);
- yp = mpnew(0);
- yq = mpnew(0);
- zp = mpnew(0);
- zq = mpnew(0);
- for(;;){
- for(;;){
- mpnrand(p, genrandom, a);
- if(mpcmp(a, mpzero) > 0)
- break;
- }
- mpmul(a, a, t);
- mpsub(t, n, t);
- mpmod(t, p, t);
- if(mpleg(t, p) == -1)
- break;
- }
- mpadd(p, mpone, N);
- mpright(N, 1, N);
- mpmul(a, a, t);
- mpsub(t, n, t);
- mpassign(a, xp);
- uitomp(1, xq);
- uitomp(1, yp);
- uitomp(0, yq);
- while(mpcmp(N, mpzero) != 0){
- if(N->p[0] & 1){
- mpmul(xp, yp, zp);
- mpmul(xq, yq, zq);
- mpmul(zq, t, zq);
- mpadd(zp, zq, zp);
- mpmod(zp, p, zp);
- mpmul(xp, yq, zq);
- mpmul(xq, yp, s);
- mpadd(zq, s, zq);
- mpmod(zq, p, yq);
- mpassign(zp, yp);
- }
- mpmul(xp, xp, zp);
- mpmul(xq, xq, zq);
- mpmul(zq, t, zq);
- mpadd(zp, zq, zp);
- mpmod(zp, p, zp);
- mpmul(xp, xq, zq);
- mpadd(zq, zq, zq);
- mpmod(zq, p, xq);
- mpassign(zp, xp);
- mpright(N, 1, N);
- }
- if(mpcmp(yq, mpzero) != 0)
- abort();
- mpassign(yp, r);
- mpfree(a);
- mpfree(t);
- mpfree(s);
- mpfree(N);
- mpfree(xp);
- mpfree(xq);
- mpfree(yp);
- mpfree(yq);
- mpfree(zp);
- mpfree(zq);
- return 1;
-}
-
-ECpoint*
-strtoec(ECdomain *dom, char *s, char **rptr, ECpoint *ret)
-{
- int allocd, o;
- mpint *r;
-
- allocd = 0;
- if(ret == nil){
- allocd = 1;
- ret = mallocz(sizeof(*ret), 1);
- if(ret == nil)
- return nil;
- ret->x = mpnew(0);
- ret->y = mpnew(0);
- }
- ret->inf = 0;
- o = 0;
- switch(octet(&s)){
- case 0:
- ret->inf = 1;
- break;
- case 3:
- o = 1;
- case 2:
- if(halfpt(dom, s, &s, ret->x) == nil)
- goto err;
- r = mpnew(0);
- mpmul(ret->x, ret->x, r);
- mpadd(r, dom->a, r);
- mpmul(r, ret->x, r);
- mpadd(r, dom->b, r);
- if(!mpsqrt(r, dom->p, r)){
- mpfree(r);
- goto err;
- }
- if((r->p[0] & 1) != o)
- mpsub(dom->p, r, r);
- mpassign(r, ret->y);
- mpfree(r);
- if(!ecverify(dom, ret))
- goto err;
- break;
- case 4:
- if(halfpt(dom, s, &s, ret->x) == nil)
- goto err;
- if(halfpt(dom, s, &s, ret->y) == nil)
- goto err;
- if(!ecverify(dom, ret))
- goto err;
- break;
- }
- if(ret->z != nil && !ret->inf)
- mpassign(mpone, ret->z);
- return ret;
-
-err:
- if(rptr)
- *rptr = s;
- if(allocd){
- mpfree(ret->x);
- mpfree(ret->y);
- free(ret);
- }
- return nil;
-}
-
-ECpriv*
-ecgen(ECdomain *dom, ECpriv *p)
-{
- if(p == nil){
- p = mallocz(sizeof(*p), 1);
- if(p == nil)
- return nil;
- p->a.x = mpnew(0);
- p->a.y = mpnew(0);
- p->d = mpnew(0);
- }
- for(;;){
- mpnrand(dom->n, genrandom, p->d);
- if(mpcmp(p->d, mpzero) > 0)
- break;
- }
- ecmul(dom, &dom->G, p->d, &p->a);
- return p;
-}
-
-void
-ecdsasign(ECdomain *dom, ECpriv *priv, uchar *dig, int len, mpint *r, mpint *s)
-{
- ECpriv tmp;
- mpint *E, *t;
-
- tmp.a.x = mpnew(0);
- tmp.a.y = mpnew(0);
- tmp.a.z = nil;
- tmp.d = mpnew(0);
- E = betomp(dig, len, nil);
- t = mpnew(0);
- if(mpsignif(dom->n) < 8*len)
- mpright(E, 8*len - mpsignif(dom->n), E);
- for(;;){
- ecgen(dom, &tmp);
- mpmod(tmp.a.x, dom->n, r);
- if(mpcmp(r, mpzero) == 0)
- continue;
- mpmul(r, priv->d, s);
- mpadd(E, s, s);
- mpinvert(tmp.d, dom->n, t);
- mpmodmul(s, t, dom->n, s);
- if(mpcmp(s, mpzero) != 0)
- break;
- }
- mpfree(t);
- mpfree(E);
- mpfree(tmp.a.x);
- mpfree(tmp.a.y);
- mpfree(tmp.d);
-}
-
-int
-ecdsaverify(ECdomain *dom, ECpub *pub, uchar *dig, int len, mpint *r, mpint *s)
-{
- mpint *E, *t, *u1, *u2;
- ECpoint R, S;
- int ret;
-
- if(mpcmp(r, mpone) < 0 || mpcmp(s, mpone) < 0 || mpcmp(r, dom->n) >= 0 || mpcmp(r, dom->n) >= 0)
- return 0;
- E = betomp(dig, len, nil);
- if(mpsignif(dom->n) < 8*len)
- mpright(E, 8*len - mpsignif(dom->n), E);
- t = mpnew(0);
- u1 = mpnew(0);
- u2 = mpnew(0);
- R.x = mpnew(0);
- R.y = mpnew(0);
- R.z = mpnew(0);
- S.x = mpnew(0);
- S.y = mpnew(0);
- S.z = mpnew(0);
- mpinvert(s, dom->n, t);
- mpmodmul(E, t, dom->n, u1);
- mpmodmul(r, t, dom->n, u2);
- ecmul(dom, &dom->G, u1, &R);
- ecmul(dom, pub, u2, &S);
- ecadd(dom, &R, &S, &R);
- ret = 0;
- if(!R.inf){
- jacobian_affine(dom->p, R.x, R.y, R.z);
- mpmod(R.x, dom->n, t);
- ret = mpcmp(r, t) == 0;
- }
- mpfree(E);
- mpfree(t);
- mpfree(u1);
- mpfree(u2);
- mpfree(R.x);
- mpfree(R.y);
- mpfree(R.z);
- mpfree(S.x);
- mpfree(S.y);
- mpfree(S.z);
- return ret;
-}
-
-static char *code = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
-
-void
-base58enc(uchar *src, char *dst, int len)
-{
- mpint *n, *r, *b;
- char *sdst, t;
-
- sdst = dst;
- n = betomp(src, len, nil);
- b = uitomp(58, nil);
- r = mpnew(0);
- while(mpcmp(n, mpzero) != 0){
- mpdiv(n, b, n, r);
- *dst++ = code[mptoui(r)];
- }
- for(; *src == 0; src++)
- *dst++ = code[0];
- dst--;
- while(dst > sdst){
- t = *sdst;
- *sdst++ = *dst;
- *dst-- = t;
- }
-}
-
-int
-base58dec(char *src, uchar *dst, int len)
-{
- mpint *n, *b, *r;
- char *t;
-
- n = mpnew(0);
- r = mpnew(0);
- b = uitomp(58, nil);
- for(; *src; src++){
- t = strchr(code, *src);
- if(t == nil){
- mpfree(n);
- mpfree(r);
- mpfree(b);
- werrstr("invalid base58 char");
- return -1;
- }
- uitomp(t - code, r);
- mpmul(n, b, n);
- mpadd(n, r, n);
- }
- mptober(n, dst, len);
- mpfree(n);
- mpfree(r);
- mpfree(b);
- return 0;
-}
-
-void
-ecdominit(ECdomain *dom, void (*init)(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h))
-{
- memset(dom, 0, sizeof(*dom));
- dom->p = mpnew(0);
- dom->a = mpnew(0);
- dom->b = mpnew(0);
- dom->G.x = mpnew(0);
- dom->G.y = mpnew(0);
- dom->n = mpnew(0);
- dom->h = mpnew(0);
- if(init){
- (*init)(dom->p, dom->a, dom->b, dom->G.x, dom->G.y, dom->n, dom->h);
- dom->p = mpfield(dom->p);
- }
-}
-
-void
-ecdomfree(ECdomain *dom)
-{
- mpfree(dom->p);
- mpfree(dom->a);
- mpfree(dom->b);
- mpfree(dom->G.x);
- mpfree(dom->G.y);
- mpfree(dom->n);
- mpfree(dom->h);
- memset(dom, 0, sizeof(*dom));
-}
-
-int
-ecencodepub(ECdomain *dom, ECpub *pub, uchar *data, int len)
-{
- int n;
-
- n = (mpsignif(dom->p)+7)/8;
- if(len < 1 + 2*n)
- return 0;
- len = 1 + 2*n;
- data[0] = 0x04;
- mptober(pub->x, data+1, n);
- mptober(pub->y, data+1+n, n);
- return len;
-}
-
-ECpub*
-ecdecodepub(ECdomain *dom, uchar *data, int len)
-{
- ECpub *pub;
- int n;
-
- n = (mpsignif(dom->p)+7)/8;
- if(len != 1 + 2*n || data[0] != 0x04)
- return nil;
- pub = mallocz(sizeof(*pub), 1);
- if(pub == nil)
- return nil;
- pub->x = betomp(data+1, n, nil);
- pub->y = betomp(data+1+n, n, nil);
- if(!ecpubverify(dom, pub)){
- ecpubfree(pub);
- pub = nil;
- }
- return pub;
-}
-
-void
-ecpubfree(ECpub *p)
-{
- if(p == nil)
- return;
- mpfree(p->x);
- mpfree(p->y);
- free(p);
-}
--- a/libsec/fastrand.c
+++ /dev/null
@@ -1,15 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-/*
- * use the X917 random number generator to create random
- * numbers (faster than truerand() but not as random).
- */
-ulong
-fastrand(void)
-{
- ulong x;
-
- genrandom((uchar*)&x, sizeof x);
- return x;
-}
--- a/libsec/genrandom.c
+++ /dev/null
@@ -1,44 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-static void
-init(Chachastate *cs)
-{
- ulong seed[11];
- int i;
-
- for(i=0; i<nelem(seed); i++)
- seed[i] = truerand();
-
- setupChachastate(cs, (uchar*)&seed[0], 32, (uchar*)&seed[8], 12, 20);
- memset(seed, 0, sizeof(seed));
-}
-
-static void
-fill(Chachastate *cs, uchar *p, int n)
-{
- Chachastate c;
-
- c = *cs;
- chacha_encrypt((uchar*)&cs->input[4], 32, &c);
- if(++cs->input[13] == 0)
- if(++cs->input[14] == 0)
- ++cs->input[15];
-
- chacha_encrypt(p, n, &c);
- memset(&c, 0, sizeof(c));
-}
-
-void
-genrandom(uchar *p, int n)
-{
- static QLock lk;
- static Chachastate cs;
-
- qlock(&lk);
- if(cs.rounds == 0)
- init(&cs);
- cs.input[4] ^= getpid(); /* fork protection */
- fill(&cs, p, n);
- qunlock(&lk);
-}
--- a/libsec/hkdf.c
+++ /dev/null
@@ -1,36 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-/* rfc5869 */
-void
-hkdf_x(uchar *salt, ulong nsalt, uchar *info, ulong ninfo,
- uchar *key, ulong nkey, uchar *d, ulong dlen,
- DigestState* (*x)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*), int xlen)
-{
- uchar prk[256], tmp[256], cnt;
- DigestState *ds;
-
- assert(xlen <= sizeof(tmp));
-
- memset(tmp, 0, xlen);
- if(nsalt == 0){
- salt = tmp;
- nsalt = xlen;
- }
- /* note that salt and key are swapped in this case */
- (*x)(key, nkey, salt, nsalt, prk, nil);
- ds = nil;
- for(cnt=1;; cnt++) {
- if(ninfo > 0)
- ds = (*x)(info, ninfo, prk, xlen, nil, ds);
- (*x)(&cnt, 1, prk, xlen, tmp, ds);
- if(dlen <= xlen){
- memmove(d, tmp, dlen);
- break;
- }
- memmove(d, tmp, xlen);
- dlen -= xlen;
- d += xlen;
- ds = (*x)(tmp, xlen, prk, xlen, nil, nil);
- }
-}
--- a/libsec/hmac.c
+++ /dev/null
@@ -1,46 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-/* rfc2104 */
-DigestState*
-hmac_x(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s,
- DigestState*(*x)(uchar*, ulong, uchar*, DigestState*), int xlen)
-{
- int i;
- uchar pad[Hmacblksz+1], innerdigest[256];
-
- if(xlen > sizeof(innerdigest))
- return nil;
- if(klen > Hmacblksz){
- if(xlen > Hmacblksz)
- return nil;
- (*x)(key, klen, innerdigest, nil);
- key = innerdigest;
- klen = xlen;
- }
-
- /* first time through */
- if(s == nil || s->seeded == 0){
- memset(pad, 0x36, Hmacblksz);
- pad[Hmacblksz] = 0;
- for(i = 0; i < klen; i++)
- pad[i] ^= key[i];
- s = (*x)(pad, Hmacblksz, nil, s);
- if(s == nil)
- return nil;
- }
-
- s = (*x)(p, len, nil, s);
- if(digest == nil)
- return s;
-
- /* last time through */
- memset(pad, 0x5c, Hmacblksz);
- pad[Hmacblksz] = 0;
- for(i = 0; i < klen; i++)
- pad[i] ^= key[i];
- (*x)(nil, 0, innerdigest, s);
- s = (*x)(pad, Hmacblksz, nil, nil);
- (*x)(innerdigest, xlen, digest, s);
- return nil;
-}
--- a/libsec/jacobian.c
+++ /dev/null
@@ -1,166 +1,0 @@
-#include "os.h"
-#include <mp.h>
-void jacobian_new(mpint *x, mpint *y, mpint *z, mpint *X, mpint *Y, mpint *Z){
- mpassign(x, X);
- mpassign(y, Y);
- mpassign(z, Z);
- }
-void jacobian_inf(mpint *X, mpint *Y, mpint *Z){
- jacobian_new(mpzero, mpone, mpzero, X, Y, Z);
- }
-void jacobian_affine(mpint *p, mpint *X, mpint *Y, mpint *Z){
- mpint *ZZZ = mpnew(0);
- mpint *ZZ = mpnew(0);
- if(mpcmp(Z, mpzero) != 0){
- mpmodmul(Z, Z, p, ZZ);
- mpmodmul(ZZ, Z, p, ZZZ);
- mpint *tmp1 = mpnew(0);
- mpinvert(ZZ, p, tmp1);
- mpmodmul(X, tmp1, p, X);
- mpfree(tmp1);
- tmp1 = mpnew(0);
- mpinvert(ZZZ, p, tmp1);
- mpmodmul(Y, tmp1, p, Y);
- mpfree(tmp1);
- mpassign(mpone, Z);
- }
- mpfree(ZZZ);
- mpfree(ZZ);
- }
-void jacobian_dbl(mpint *p, mpint *a, mpint *X1, mpint *Y1, mpint *Z1, mpint *X3, mpint *Y3, mpint *Z3){
- mpint *M = mpnew(0);
- mpint *S = mpnew(0);
- mpint *ZZ = mpnew(0);
- mpint *YYYY = mpnew(0);
- mpint *YY = mpnew(0);
- mpint *XX = mpnew(0);
- if(mpcmp(Y1, mpzero) == 0){
- jacobian_inf(X3, Y3, Z3);
- }else{
- mpmodmul(X1, X1, p, XX);
- mpmodmul(Y1, Y1, p, YY);
- mpmodmul(YY, YY, p, YYYY);
- mpmodmul(Z1, Z1, p, ZZ);
- mpint *tmp1 = mpnew(0);
- mpmodadd(X1, YY, p, tmp1);
- mpmodmul(tmp1, tmp1, p, tmp1);
- mpmodsub(tmp1, XX, p, tmp1);
- mpmodsub(tmp1, YYYY, p, tmp1);
- mpmodadd(tmp1, tmp1, p, S); // 2*tmp1
- mpfree(tmp1);
- tmp1 = mpnew(0);
- uitomp(3UL, tmp1);
- mpmodmul(tmp1, XX, p, M);
- mpfree(tmp1);
- tmp1 = mpnew(0);
- mpint *tmp2 = mpnew(0);
- mpmodmul(ZZ, ZZ, p, tmp2);
- mpmodmul(a, tmp2, p, tmp1);
- mpfree(tmp2);
- mpmodadd(M, tmp1, p, M);
- mpfree(tmp1);
- mpmodadd(Y1, Z1, p, Z3);
- mpmodmul(Z3, Z3, p, Z3);
- mpmodsub(Z3, YY, p, Z3);
- mpmodsub(Z3, ZZ, p, Z3);
- mpmodmul(M, M, p, X3);
- tmp1 = mpnew(0);
- mpmodadd(S, S, p, tmp1); // 2*S
- mpmodsub(X3, tmp1, p, X3);
- mpfree(tmp1);
- tmp1 = mpnew(0);
- mpmodsub(S, X3, p, tmp1);
- mpmodmul(M, tmp1, p, Y3);
- mpfree(tmp1);
- tmp1 = mpnew(0);
- tmp2 = mpnew(0);
- uitomp(8UL, tmp2);
- mpmodmul(tmp2, YYYY, p, tmp1);
- mpfree(tmp2);
- mpmodsub(Y3, tmp1, p, Y3);
- mpfree(tmp1);
- }
- mpfree(M);
- mpfree(S);
- mpfree(ZZ);
- mpfree(YYYY);
- mpfree(YY);
- mpfree(XX);
- }
-void jacobian_add(mpint *p, mpint *a, mpint *X1, mpint *Y1, mpint *Z1, mpint *X2, mpint *Y2, mpint *Z2, mpint *X3, mpint *Y3, mpint *Z3){
- mpint *V = mpnew(0);
- mpint *r = mpnew(0);
- mpint *J = mpnew(0);
- mpint *I = mpnew(0);
- mpint *H = mpnew(0);
- mpint *S2 = mpnew(0);
- mpint *S1 = mpnew(0);
- mpint *U2 = mpnew(0);
- mpint *U1 = mpnew(0);
- mpint *Z2Z2 = mpnew(0);
- mpint *Z1Z1 = mpnew(0);
- mpmodmul(Z1, Z1, p, Z1Z1);
- mpmodmul(Z2, Z2, p, Z2Z2);
- mpmodmul(X1, Z2Z2, p, U1);
- mpmodmul(X2, Z1Z1, p, U2);
- mpint *tmp1 = mpnew(0);
- mpmodmul(Y1, Z2, p, tmp1);
- mpmodmul(tmp1, Z2Z2, p, S1);
- mpfree(tmp1);
- tmp1 = mpnew(0);
- mpmodmul(Y2, Z1, p, tmp1);
- mpmodmul(tmp1, Z1Z1, p, S2);
- mpfree(tmp1);
- if(mpcmp(U1, U2) == 0){
- if(mpcmp(S1, S2) != 0){
- jacobian_inf(X3, Y3, Z3);
- }else{
- jacobian_dbl(p, a, X1, Y1, Z1, X3, Y3, Z3);
- }
- }else{
- mpmodsub(U2, U1, p, H);
- mpmodadd(H, H, p, I); // 2*H
- mpmodmul(I, I, p, I);
- mpmodmul(H, I, p, J);
- mpint *tmp2 = mpnew(0);
- mpmodsub(S2, S1, p, tmp2);
- mpmodadd(tmp2, tmp2, p, r); // 2*tmp2
- mpfree(tmp2);
- mpmodmul(U1, I, p, V);
- mpmodmul(r, r, p, X3);
- mpmodsub(X3, J, p, X3);
- tmp2 = mpnew(0);
- mpmodadd(V, V, p, tmp2); // 2*V
- mpmodsub(X3, tmp2, p, X3);
- mpfree(tmp2);
- tmp2 = mpnew(0);
- mpmodsub(V, X3, p, tmp2);
- mpmodmul(r, tmp2, p, Y3);
- mpfree(tmp2);
- tmp2 = mpnew(0);
- mpint *tmp3 = mpnew(0);
- mpmodadd(S1, S1, p, tmp3); // 2*S1
- mpmodmul(tmp3, J, p, tmp2);
- mpfree(tmp3);
- mpmodsub(Y3, tmp2, p, Y3);
- mpfree(tmp2);
- tmp2 = mpnew(0);
- mpmodadd(Z1, Z2, p, tmp2);
- mpmodmul(tmp2, tmp2, p, tmp2);
- mpmodsub(tmp2, Z1Z1, p, tmp2);
- mpmodsub(tmp2, Z2Z2, p, tmp2);
- mpmodmul(tmp2, H, p, Z3);
- mpfree(tmp2);
- }
- mpfree(V);
- mpfree(r);
- mpfree(J);
- mpfree(I);
- mpfree(H);
- mpfree(S2);
- mpfree(S1);
- mpfree(U2);
- mpfree(U1);
- mpfree(Z2Z2);
- mpfree(Z1Z1);
- }
--- a/libsec/md5.c
+++ /dev/null
@@ -1,154 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-/*
- * rfc1321 requires that I include this. The code is new. The constants
- * all come from the rfc (hence the copyright). We trade a table for the
- * macros in rfc. The total size is a lot less. -- presotto
- *
- * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
- * rights reserved.
- *
- * License to copy and use this software is granted provided that it
- * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
- * Algorithm" in all material mentioning or referencing this software
- * or this function.
- *
- * License is also granted to make and use derivative works provided
- * that such works are identified as "derived from the RSA Data
- * Security, Inc. MD5 Message-Digest Algorithm" in all material
- * mentioning or referencing the derived work.
- *
- * RSA Data Security, Inc. makes no representations concerning either
- * the merchantability of this software or the suitability of this
- * software forany particular purpose. It is provided "as is"
- * without express or implied warranty of any kind.
- * These notices must be retained in any copies of any part of this
- * documentation and/or software.
- */
-
-static void encode(uchar*, u32int*, ulong);
-
-extern void _md5block(uchar*, ulong, u32int*);
-
-MD5state*
-md5(uchar *p, ulong len, uchar *digest, MD5state *s)
-{
- u32int x[16];
- uchar buf[128];
- int i;
- uchar *e;
-
- if(s == nil){
- s = malloc(sizeof(*s));
- if(s == nil)
- return nil;
- memset(s, 0, sizeof(*s));
- s->malloced = 1;
- }
-
- if(s->seeded == 0){
- /* seed the state, these constants would look nicer big-endian */
- s->state[0] = 0x67452301;
- s->state[1] = 0xefcdab89;
- s->state[2] = 0x98badcfe;
- s->state[3] = 0x10325476;
- s->seeded = 1;
- }
-
- /* fill out the partial 64 byte block from previous calls */
- if(s->blen){
- i = 64 - s->blen;
- if(len < i)
- i = len;
- memmove(s->buf + s->blen, p, i);
- len -= i;
- s->blen += i;
- p += i;
- if(s->blen == 64){
- _md5block(s->buf, s->blen, s->state);
- s->len += s->blen;
- s->blen = 0;
- }
- }
-
- /* do 64 byte blocks */
- i = len & ~0x3f;
- if(i){
- _md5block(p, i, s->state);
- s->len += i;
- len -= i;
- p += i;
- }
-
- /* save the left overs if not last call */
- if(digest == 0){
- if(len){
- memmove(s->buf, p, len);
- s->blen += len;
- }
- return s;
- }
-
- /*
- * this is the last time through, pad what's left with 0x80,
- * 0's, and the input count to create a multiple of 64 bytes
- */
- if(s->blen){
- p = s->buf;
- len = s->blen;
- } else {
- memmove(buf, p, len);
- p = buf;
- }
- s->len += len;
- e = p + len;
- if(len < 56)
- i = 56 - len;
- else
- i = 120 - len;
- memset(e, 0, i);
- *e = 0x80;
- len += i;
-
- /* append the count */
- x[0] = s->len<<3;
- x[1] = s->len>>29;
- encode(p+len, x, 8);
-
- /* digest the last part */
- _md5block(p, len+8, s->state);
- s->len += len;
-
- /* return result and free state */
- encode(digest, s->state, MD5dlen);
- if(s->malloced == 1)
- free(s);
- return nil;
-}
-
-/*
- * encodes input (u32int) into output (uchar). Assumes len is
- * a multiple of 4.
- */
-static void
-encode(uchar *output, u32int *input, ulong len)
-{
- u32int x;
- uchar *e;
-
- for(e = output + len; output < e;) {
- x = *input++;
- *output++ = x;
- *output++ = x >> 8;
- *output++ = x >> 16;
- *output++ = x >> 24;
- }
-}
-
-DigestState*
-hmac_md5(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest,
- DigestState *s)
-{
- return hmac_x(p, len, key, klen, digest, s, md5, MD5dlen);
-}
--- a/libsec/md5block.c
+++ /dev/null
@@ -1,267 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-/*
- * rfc1321 requires that I include this. The code is new. The constants
- * all come from the rfc (hence the copyright). We trade a table for the
- * macros in rfc. The total size is a lot less. -- presotto
- *
- * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
- * rights reserved.
- *
- * License to copy and use this software is granted provided that it
- * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
- * Algorithm" in all material mentioning or referencing this software
- * or this function.
- *
- * License is also granted to make and use derivative works provided
- * that such works are identified as "derived from the RSA Data
- * Security, Inc. MD5 Message-Digest Algorithm" in all material
- * mentioning or referencing the derived work.
- *
- * RSA Data Security, Inc. makes no representations concerning either
- * the merchantability of this software or the suitability of this
- * software forany particular purpose. It is provided "as is"
- * without express or implied warranty of any kind.
- * These notices must be retained in any copies of any part of this
- * documentation and/or software.
- */
-
-/*
- * Rotate ammounts used in the algorithm
- */
-enum
-{
- S11= 7,
- S12= 12,
- S13= 17,
- S14= 22,
-
- S21= 5,
- S22= 9,
- S23= 14,
- S24= 20,
-
- S31= 4,
- S32= 11,
- S33= 16,
- S34= 23,
-
- S41= 6,
- S42= 10,
- S43= 15,
- S44= 21,
-};
-
-static u32int md5tab[] =
-{
- /* round 1 */
-/*[0]*/ 0xd76aa478,
- 0xe8c7b756,
- 0x242070db,
- 0xc1bdceee,
- 0xf57c0faf,
- 0x4787c62a,
- 0xa8304613,
- 0xfd469501,
- 0x698098d8,
- 0x8b44f7af,
- 0xffff5bb1,
- 0x895cd7be,
- 0x6b901122,
- 0xfd987193,
- 0xa679438e,
- 0x49b40821,
-
- /* round 2 */
-/*[16]*/0xf61e2562,
- 0xc040b340,
- 0x265e5a51,
- 0xe9b6c7aa,
- 0xd62f105d,
- 0x2441453,
- 0xd8a1e681,
- 0xe7d3fbc8,
- 0x21e1cde6,
- 0xc33707d6,
- 0xf4d50d87,
- 0x455a14ed,
- 0xa9e3e905,
- 0xfcefa3f8,
- 0x676f02d9,
- 0x8d2a4c8a,
-
- /* round 3 */
-/*[32]*/0xfffa3942,
- 0x8771f681,
- 0x6d9d6122,
- 0xfde5380c,
- 0xa4beea44,
- 0x4bdecfa9,
- 0xf6bb4b60,
- 0xbebfbc70,
- 0x289b7ec6,
- 0xeaa127fa,
- 0xd4ef3085,
- 0x4881d05,
- 0xd9d4d039,
- 0xe6db99e5,
- 0x1fa27cf8,
- 0xc4ac5665,
-
- /* round 4 */
-/*[48]*/0xf4292244,
- 0x432aff97,
- 0xab9423a7,
- 0xfc93a039,
- 0x655b59c3,
- 0x8f0ccc92,
- 0xffeff47d,
- 0x85845dd1,
- 0x6fa87e4f,
- 0xfe2ce6e0,
- 0xa3014314,
- 0x4e0811a1,
- 0xf7537e82,
- 0xbd3af235,
- 0x2ad7d2bb,
- 0xeb86d391,
-};
-
-static void decode(u32int*, uchar*, ulong);
-extern void _md5block(uchar *p, ulong len, u32int *s);
-
-void
-_md5block(uchar *p, ulong len, u32int *s)
-{
- u32int a, b, c, d, sh;
- u32int *t;
- uchar *end;
- u32int x[16];
-
- for(end = p+len; p < end; p += 64){
- a = s[0];
- b = s[1];
- c = s[2];
- d = s[3];
-
- decode(x, p, 64);
-
- t = md5tab;
- sh = 0;
- for(; sh != 16; t += 4){
- a += ((c ^ d) & b) ^ d;
- a += x[sh] + t[0];
- a = (a << S11) | (a >> (32 - S11));
- a += b;
-
- d += ((b ^ c) & a) ^ c;
- d += x[sh + 1] + t[1];
- d = (d << S12) | (d >> (32 - S12));
- d += a;
-
- c += ((a ^ b) & d) ^ b;
- c += x[sh + 2] + t[2];
- c = (c << S13) | (c >> (32 - S13));
- c += d;
-
- b += ((d ^ a) & c) ^ a;
- b += x[sh + 3] + t[3];
- b = (b << S14) | (b >> (32 - S14));
- b += c;
-
- sh += 4;
- }
- sh = 1;
- for(; sh != 1+20*4; t += 4){
- a += ((b ^ c) & d) ^ c;
- a += x[sh & 0xf] + t[0];
- a = (a << S21) | (a >> (32 - S21));
- a += b;
-
- d += ((a ^ b) & c) ^ b;
- d += x[(sh + 5) & 0xf] + t[1];
- d = (d << S22) | (d >> (32 - S22));
- d += a;
-
- c += ((d ^ a) & b) ^ a;
- c += x[(sh + 10) & 0xf] + t[2];
- c = (c << S23) | (c >> (32 - S23));
- c += d;
-
- b += ((c ^ d) & a) ^ d;
- b += x[(sh + 15) & 0xf] + t[3];
- b = (b << S24) | (b >> (32 - S24));
- b += c;
-
- sh += 20;
- }
- sh = 5;
- for(; sh != 5+12*4; t += 4){
- a += b ^ c ^ d;
- a += x[sh & 0xf] + t[0];
- a = (a << S31) | (a >> (32 - S31));
- a += b;
-
- d += a ^ b ^ c;
- d += x[(sh + 3) & 0xf] + t[1];
- d = (d << S32) | (d >> (32 - S32));
- d += a;
-
- c += d ^ a ^ b;
- c += x[(sh + 6) & 0xf] + t[2];
- c = (c << S33) | (c >> (32 - S33));
- c += d;
-
- b += c ^ d ^ a;
- b += x[(sh + 9) & 0xf] + t[3];
- b = (b << S34) | (b >> (32 - S34));
- b += c;
-
- sh += 12;
- }
- sh = 0;
- for(; sh != 28*4; t += 4){
- a += c ^ (b | ~d);
- a += x[sh & 0xf] + t[0];
- a = (a << S41) | (a >> (32 - S41));
- a += b;
-
- d += b ^ (a | ~c);
- d += x[(sh + 7) & 0xf] + t[1];
- d = (d << S42) | (d >> (32 - S42));
- d += a;
-
- c += a ^ (d | ~b);
- c += x[(sh + 14) & 0xf] + t[2];
- c = (c << S43) | (c >> (32 - S43));
- c += d;
-
- b += d ^ (c | ~a);
- b += x[(sh + 21) & 0xf] + t[3];
- b = (b << S44) | (b >> (32 - S44));
- b += c;
-
- sh += 28;
- }
-
- s[0] += a;
- s[1] += b;
- s[2] += c;
- s[3] += d;
- }
-}
-
-/*
- * decodes input (uchar) into output (u32int). Assumes len is
- * a multiple of 4.
- */
-static void
-decode(u32int *output, uchar *input, ulong len)
-{
- uchar *e;
-
- for(e = input+len; input < e; input += 4)
- *output++ = input[0] | (input[1] << 8) |
- (input[2] << 16) | (input[3] << 24);
-}
--- a/libsec/nfastrand.c
+++ /dev/null
@@ -1,22 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-#define Maxrand ((1UL<<31)-1)
-
-ulong
-nfastrand(ulong n)
-{
- ulong m, r;
-
- /*
- * set m to the maximum multiple of n <= 2^31-1
- * so we want a random number < m.
- */
- if(n > Maxrand)
- sysfatal("nfastrand: n too large");
-
- m = Maxrand - Maxrand % n;
- while((r = fastrand()) >= m)
- ;
- return r%n;
-}
--- a/libsec/os.h
+++ /dev/null
@@ -1,2 +1,0 @@
-#include <u.h>
-#include <libc.h>
--- a/libsec/pbkdf2.c
+++ /dev/null
@@ -1,32 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-/* rfc2898 */
-void
-pbkdf2_x(uchar *p, ulong plen, uchar *s, ulong slen,
- ulong rounds, uchar *d, ulong dlen,
- DigestState* (*x)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*), int xlen)
-{
- uchar block[256], tmp[256];
- ulong i, j, k, n;
- DigestState *ds;
-
- assert(xlen <= sizeof(tmp));
-
- for(i = 1; dlen > 0; i++, d += n, dlen -= n){
- tmp[3] = i;
- tmp[2] = i >> 8;
- tmp[1] = i >> 16;
- tmp[0] = i >> 24;
- ds = (*x)(s, slen, p, plen, nil, nil);
- (*x)(tmp, 4, p, plen, block, ds);
- memmove(tmp, block, xlen);
- for(j = 1; j < rounds; j++){
- (*x)(tmp, xlen, p, plen, tmp, nil);
- for(k=0; k<xlen; k++)
- block[k] ^= tmp[k];
- }
- n = dlen > xlen ? xlen : dlen;
- memmove(d, block, n);
- }
-}
--- a/libsec/poly1305.c
+++ /dev/null
@@ -1,195 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-/*
- poly1305 implementation using 32 bit * 32 bit = 64 bit multiplication and 64 bit addition
-
- derived from http://github.com/floodberry/poly1305-donna
-*/
-
-#define U8TO32(p) ((u32int)(p)[0] | (u32int)(p)[1]<<8 | (u32int)(p)[2]<<16 | (u32int)(p)[3]<<24)
-#define U32TO8(p, v) (p)[0]=(v), (p)[1]=(v)>>8, (p)[2]=(v)>>16, (p)[3]=(v)>>24
-
-/* (r,s) = (key[0:15],key[16:31]), the one time key */
-DigestState*
-poly1305(uchar *m, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s)
-{
- u32int r0,r1,r2,r3,r4, s1,s2,s3,s4, h0,h1,h2,h3,h4, g0,g1,g2,g3,g4;
- u64int d0,d1,d2,d3,d4, f;
- u32int hibit, mask, c;
-
- if(s == nil){
- s = malloc(sizeof(*s));
- if(s == nil)
- return nil;
- memset(s, 0, sizeof(*s));
- s->malloced = 1;
- }
-
- if(s->seeded == 0){
- assert(klen == 32);
-
- /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
- s->state[0] = (U8TO32(&key[ 0]) ) & 0x3ffffff;
- s->state[1] = (U8TO32(&key[ 3]) >> 2) & 0x3ffff03;
- s->state[2] = (U8TO32(&key[ 6]) >> 4) & 0x3ffc0ff;
- s->state[3] = (U8TO32(&key[ 9]) >> 6) & 0x3f03fff;
- s->state[4] = (U8TO32(&key[12]) >> 8) & 0x00fffff;
-
- /* h = 0 */
- s->state[5] = 0;
- s->state[6] = 0;
- s->state[7] = 0;
- s->state[8] = 0;
- s->state[9] = 0;
-
- /* save pad for later */
- s->state[10] = U8TO32(&key[16]);
- s->state[11] = U8TO32(&key[20]);
- s->state[12] = U8TO32(&key[24]);
- s->state[13] = U8TO32(&key[28]);
-
- s->seeded = 1;
- }
-
- if(s->blen){
- c = 16 - s->blen;
- if(c > len)
- c = len;
- memmove(s->buf + s->blen, m, c);
- len -= c, m += c;
- s->blen += c;
- if(s->blen == 16){
- s->blen = 0;
- poly1305(s->buf, 16, key, klen, nil, s);
- } else if(len == 0){
- m = s->buf;
- len = s->blen;
- s->blen = 0;
- }
- }
-
- r0 = s->state[0];
- r1 = s->state[1];
- r2 = s->state[2];
- r3 = s->state[3];
- r4 = s->state[4];
-
- h0 = s->state[5];
- h1 = s->state[6];
- h2 = s->state[7];
- h3 = s->state[8];
- h4 = s->state[9];
-
- s1 = r1 * 5;
- s2 = r2 * 5;
- s3 = r3 * 5;
- s4 = r4 * 5;
-
- hibit = 1<<24; /* 1<<128 */
-
- while(len >= 16){
-Block:
- /* h += m[i] */
- h0 += (U8TO32(&m[0]) ) & 0x3ffffff;
- h1 += (U8TO32(&m[3]) >> 2) & 0x3ffffff;
- h2 += (U8TO32(&m[6]) >> 4) & 0x3ffffff;
- h3 += (U8TO32(&m[9]) >> 6) & 0x3ffffff;
- h4 += (U8TO32(&m[12])>> 8) | hibit;
-
- /* h *= r */
- d0 = ((u64int)h0 * r0) + ((u64int)h1 * s4) + ((u64int)h2 * s3) + ((u64int)h3 * s2) + ((u64int)h4 * s1);
- d1 = ((u64int)h0 * r1) + ((u64int)h1 * r0) + ((u64int)h2 * s4) + ((u64int)h3 * s3) + ((u64int)h4 * s2);
- d2 = ((u64int)h0 * r2) + ((u64int)h1 * r1) + ((u64int)h2 * r0) + ((u64int)h3 * s4) + ((u64int)h4 * s3);
- d3 = ((u64int)h0 * r3) + ((u64int)h1 * r2) + ((u64int)h2 * r1) + ((u64int)h3 * r0) + ((u64int)h4 * s4);
- d4 = ((u64int)h0 * r4) + ((u64int)h1 * r3) + ((u64int)h2 * r2) + ((u64int)h3 * r1) + ((u64int)h4 * r0);
-
- /* (partial) h %= p */
- c = (u32int)(d0 >> 26); h0 = (u32int)d0 & 0x3ffffff;
- d1 += c; c = (u32int)(d1 >> 26); h1 = (u32int)d1 & 0x3ffffff;
- d2 += c; c = (u32int)(d2 >> 26); h2 = (u32int)d2 & 0x3ffffff;
- d3 += c; c = (u32int)(d3 >> 26); h3 = (u32int)d3 & 0x3ffffff;
- d4 += c; c = (u32int)(d4 >> 26); h4 = (u32int)d4 & 0x3ffffff;
- h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff;
- h1 += c;
-
- len -= 16, m += 16;
- }
-
- if(len){
- s->blen = len;
- memmove(s->buf, m, len);
- }
-
- if(digest == nil){
- s->state[5] = h0;
- s->state[6] = h1;
- s->state[7] = h2;
- s->state[8] = h3;
- s->state[9] = h4;
- return s;
- }
-
- if(len){
- m = s->buf;
- m[len++] = 1;
- while(len < 16)
- m[len++] = 0;
- hibit = 0;
- goto Block;
- }
-
- c = h1 >> 26; h1 = h1 & 0x3ffffff;
- h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff;
- h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff;
- h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff;
- h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff;
- h1 += c;
-
- /* compute h + -p */
- g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff;
- g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff;
- g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff;
- g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff;
- g4 = h4 + c - (1 << 26);
-
- /* select h if h < p, or h + -p if h >= p */
- mask = (g4 >> 31) - 1;
- g0 &= mask;
- g1 &= mask;
- g2 &= mask;
- g3 &= mask;
- g4 &= mask;
- mask = ~mask;
- h0 = (h0 & mask) | g0;
- h1 = (h1 & mask) | g1;
- h2 = (h2 & mask) | g2;
- h3 = (h3 & mask) | g3;
- h4 = (h4 & mask) | g4;
-
- /* h = h % (2^128) */
- h0 = (h0 ) | (h1 << 26);
- h1 = (h1 >> 6) | (h2 << 20);
- h2 = (h2 >> 12) | (h3 << 14);
- h3 = (h3 >> 18) | (h4 << 8);
-
- /* digest = (h + pad) % (2^128) */
- f = (u64int)h0 + s->state[10] ; h0 = (u32int)f;
- f = (u64int)h1 + s->state[11] + (f >> 32); h1 = (u32int)f;
- f = (u64int)h2 + s->state[12] + (f >> 32); h2 = (u32int)f;
- f = (u64int)h3 + s->state[13] + (f >> 32); h3 = (u32int)f;
-
- U32TO8(&digest[0], h0);
- U32TO8(&digest[4], h1);
- U32TO8(&digest[8], h2);
- U32TO8(&digest[12], h3);
-
- if(s->malloced){
- memset(s, 0, sizeof(*s));
- free(s);
- return nil;
- }
-
- memset(s, 0, sizeof(*s));
- return nil;
-}
--- a/libsec/prng.c
+++ /dev/null
@@ -1,14 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-//
-// just use the libc prng to fill a buffer
-//
-void
-prng(uchar *p, int n)
-{
- uchar *e;
-
- for(e = p+n; p < e; p++)
- *p = rand();
-}
--- a/libsec/rc4.c
+++ /dev/null
@@ -1,104 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-void
-setupRC4state(RC4state *key, uchar *start, int n)
-{
- int t;
- int index2;
- uchar *state;
- uchar *p, *e, *sp, *se;
-
- state = key->state;
- se = &state[256];
- for(sp = state; sp < se; sp++)
- *sp = sp - state;
-
- key->x = 0;
- key->y = 0;
- index2 = 0;
- e = start + n;
- p = start;
- for(sp = state; sp < se; sp++)
- {
- t = *sp;
- index2 = (*p + t + index2) & 255;
- *sp = state[index2];
- state[index2] = t;
- if(++p >= e)
- p = start;
- }
-}
-
-void
-rc4(RC4state *key, uchar *p, int len)
-{
- int tx, ty;
- int x, y;
- uchar *state;
- uchar *e;
-
- x = key->x;
- y = key->y;
- state = &key->state[0];
- for(e = p + len; p < e; p++)
- {
- x = (x+1)&255;
- tx = state[x];
- y = (y+tx)&255;
- ty = state[y];
- state[x] = ty;
- state[y] = tx;
- *p ^= state[(tx+ty)&255];
- }
- key->x = x;
- key->y = y;
-}
-
-void
-rc4skip(RC4state *key, int len)
-{
- int tx, ty;
- int x, y;
- uchar *state;
- int i;
-
- x = key->x;
- y = key->y;
- state = &key->state[0];
- for(i=0; i<len; i++)
- {
- x = (x+1)&255;
- tx = state[x];
- y = (y+tx)&255;
- ty = state[y];
- state[x] = ty;
- state[y] = tx;
- }
- key->x = x;
- key->y = y;
-}
-
-void
-rc4back(RC4state *key, int len)
-{
- int tx, ty;
- int x, y;
- uchar *state;
- int i;
-
- x = key->x;
- y = key->y;
- state = &key->state[0];
- for(i=0; i<len; i++)
- {
- ty = state[x];
- tx = state[y];
- state[y] = ty;
- state[x] = tx;
- y = (y-tx)&255;
- x = (x-1)&255;
- }
- key->x = x;
- key->y = y;
-}
--- a/libsec/readcert.c
+++ /dev/null
@@ -1,63 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-static char*
-readfile(char *name)
-{
- int fd;
- char *s;
- Dir *d;
-
- fd = open(name, OREAD);
- if(fd < 0)
- return nil;
- if((d = dirfstat(fd)) == nil) {
- close(fd);
- return nil;
- }
- s = malloc(d->length + 1);
- if(s == nil || readn(fd, s, d->length) != d->length){
- free(s);
- free(d);
- close(fd);
- return nil;
- }
- close(fd);
- s[d->length] = '\0';
- free(d);
- return s;
-}
-
-uchar*
-readcert(char *filename, int *pcertlen)
-{
- char *pem;
- uchar *binary;
-
- pem = readfile(filename);
- if(pem == nil){
- werrstr("can't read %s: %r", filename);
- return nil;
- }
- binary = decodePEM(pem, "CERTIFICATE", pcertlen, nil);
- free(pem);
- if(binary == nil){
- werrstr("can't parse %s", filename);
- return nil;
- }
- return binary;
-}
-
-PEMChain *
-readcertchain(char *filename)
-{
- char *chfile;
-
- chfile = readfile(filename);
- if (chfile == nil) {
- werrstr("can't read %s: %r", filename);
- return nil;
- }
- return decodepemchain(chfile, "CERTIFICATE");
-}
-
--- a/libsec/rsaalloc.c
+++ /dev/null
@@ -1,52 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include <libsec.h>
-
-RSApub*
-rsapuballoc(void)
-{
- RSApub *rsa;
-
- rsa = mallocz(sizeof(*rsa), 1);
- if(rsa == nil)
- sysfatal("rsapuballoc");
- return rsa;
-}
-
-void
-rsapubfree(RSApub *rsa)
-{
- if(rsa == nil)
- return;
- mpfree(rsa->ek);
- mpfree(rsa->n);
- free(rsa);
-}
-
-
-RSApriv*
-rsaprivalloc(void)
-{
- RSApriv *rsa;
-
- rsa = mallocz(sizeof(*rsa), 1);
- if(rsa == nil)
- sysfatal("rsaprivalloc");
- return rsa;
-}
-
-void
-rsaprivfree(RSApriv *rsa)
-{
- if(rsa == nil)
- return;
- mpfree(rsa->pub.ek);
- mpfree(rsa->pub.n);
- mpfree(rsa->dk);
- mpfree(rsa->p);
- mpfree(rsa->q);
- mpfree(rsa->kp);
- mpfree(rsa->kq);
- mpfree(rsa->c2);
- free(rsa);
-}
--- a/libsec/rsadecrypt.c
+++ /dev/null
@@ -1,37 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include <libsec.h>
-
-// decrypt rsa using garner's algorithm for the chinese remainder theorem
-// seminumerical algorithms, knuth, pp 253-254
-// applied cryptography, menezes et al, pg 612
-mpint*
-rsadecrypt(RSApriv *rsa, mpint *in, mpint *out)
-{
- mpint *v1, *v2;
-
- if(out == nil)
- out = mpnew(0);
-
- // convert in to modular representation
- v1 = mpnew(0);
- mpmod(in, rsa->p, v1);
- v2 = mpnew(0);
- mpmod(in, rsa->q, v2);
-
- // exponentiate the modular rep
- mpexp(v1, rsa->kp, rsa->p, v1);
- mpexp(v2, rsa->kq, rsa->q, v2);
-
- // out = v1 + p*((v2-v1)*c2 mod q)
- mpsub(v2, v1, v2);
- mpmul(v2, rsa->c2, v2);
- mpmod(v2, rsa->q, v2);
- mpmul(v2, rsa->p, out);
- mpadd(v1, out, out);
-
- mpfree(v1);
- mpfree(v2);
-
- return out;
-}
--- a/libsec/rsaencrypt.c
+++ /dev/null
@@ -1,12 +1,0 @@
-#include "os.h"
-#include <mp.h>
-#include <libsec.h>
-
-mpint*
-rsaencrypt(RSApub *rsa, mpint *in, mpint *out)
-{
- if(out == nil)
- out = mpnew(0);
- mpexp(in, rsa->ek, rsa->n, out);
- return out;
-}
--- a/libsec/secp256k1.c
+++ /dev/null
@@ -1,11 +1,0 @@
-#include "os.h"
-#include <mp.h>
-void secp256k1(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h){
- strtomp("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", nil, 16, p);
- mpassign(mpzero, a);
- uitomp(7UL, b);
- strtomp("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", nil, 16, x);
- strtomp("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", nil, 16, y);
- strtomp("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", nil, 16, n);
- mpassign(mpone, h);
- }
--- a/libsec/secp256r1.c
+++ /dev/null
@@ -1,12 +1,0 @@
-#include "os.h"
-#include <mp.h>
-void secp256r1(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h){
- strtomp("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", nil, 16, p);
- uitomp(3UL, a);
- mpsub(p, a, a);
- strtomp("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", nil, 16, b);
- strtomp("6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", nil, 16, x);
- strtomp("4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", nil, 16, y);
- strtomp("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", nil, 16, n);
- mpassign(mpone, h);
- }
--- a/libsec/secp384r1.c
+++ /dev/null
@@ -1,12 +1,0 @@
-#include "os.h"
-#include <mp.h>
-void secp384r1(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h){
- strtomp("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", nil, 16, p);
- uitomp(3UL, a);
- mpsub(p, a, a);
- strtomp("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", nil, 16, b);
- strtomp("AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", nil, 16, x);
- strtomp("3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", nil, 16, y);
- strtomp("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", nil, 16, n);
- mpassign(mpone, h);
- }
--- a/libsec/sha1.c
+++ /dev/null
@@ -1,134 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-static void encode(uchar*, u32int*, ulong);
-
-extern void _sha1block(uchar*, ulong, u32int*);
-
-/*
- * we require len to be a multiple of 64 for all but
- * the last call. There must be room in the input buffer
- * to pad.
- */
-SHA1state*
-sha1(uchar *p, ulong len, uchar *digest, SHA1state *s)
-{
- uchar buf[128];
- u32int x[16];
- int i;
- uchar *e;
-
- if(s == nil){
- s = malloc(sizeof(*s));
- if(s == nil)
- return nil;
- memset(s, 0, sizeof(*s));
- s->malloced = 1;
- }
-
- if(s->seeded == 0){
- /* seed the state, these constants would look nicer big-endian */
- s->state[0] = 0x67452301;
- s->state[1] = 0xefcdab89;
- s->state[2] = 0x98badcfe;
- s->state[3] = 0x10325476;
- s->state[4] = 0xc3d2e1f0;
- s->seeded = 1;
- }
-
- /* fill out the partial 64 byte block from previous calls */
- if(s->blen){
- i = 64 - s->blen;
- if(len < i)
- i = len;
- memmove(s->buf + s->blen, p, i);
- len -= i;
- s->blen += i;
- p += i;
- if(s->blen == 64){
- _sha1block(s->buf, s->blen, s->state);
- s->len += s->blen;
- s->blen = 0;
- }
- }
-
- /* do 64 byte blocks */
- i = len & ~0x3f;
- if(i){
- _sha1block(p, i, s->state);
- s->len += i;
- len -= i;
- p += i;
- }
-
- /* save the left overs if not last call */
- if(digest == 0){
- if(len){
- memmove(s->buf, p, len);
- s->blen += len;
- }
- return s;
- }
-
- /*
- * this is the last time through, pad what's left with 0x80,
- * 0's, and the input count to create a multiple of 64 bytes
- */
- if(s->blen){
- p = s->buf;
- len = s->blen;
- } else {
- memmove(buf, p, len);
- p = buf;
- }
- s->len += len;
- e = p + len;
- if(len < 56)
- i = 56 - len;
- else
- i = 120 - len;
- memset(e, 0, i);
- *e = 0x80;
- len += i;
-
- /* append the count */
- x[0] = s->len>>29;
- x[1] = s->len<<3;
- encode(p+len, x, 8);
-
- /* digest the last part */
- _sha1block(p, len+8, s->state);
- s->len += len+8;
-
- /* return result and free state */
- encode(digest, s->state, SHA1dlen);
- if(s->malloced == 1)
- free(s);
- return nil;
-}
-
-/*
- * encodes input (ulong) into output (uchar). Assumes len is
- * a multiple of 4.
- */
-static void
-encode(uchar *output, u32int *input, ulong len)
-{
- u32int x;
- uchar *e;
-
- for(e = output + len; output < e;) {
- x = *input++;
- *output++ = x >> 24;
- *output++ = x >> 16;
- *output++ = x >> 8;
- *output++ = x;
- }
-}
-
-DigestState*
-hmac_sha1(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest,
- DigestState *s)
-{
- return hmac_x(p, len, key, klen, digest, s, sha1, SHA1dlen);
-}
--- a/libsec/sha1block.c
+++ /dev/null
@@ -1,137 +1,0 @@
-#include "os.h"
-
-#define ROTL(x,n) (((x)<<n)|((x)>>(32-n)))
-
-#define F0(x,y,z) (0x5a827999 + ((z) ^ ((x) & ((y) ^ (z)))))
-#define F1(x,y,z) (0x6ed9eba1 + ((x) ^ (y) ^ (z)))
-#define F2(x,y,z) (0x8f1bbcdc + (((x) & (y)) | (((x) | (y)) & (z))))
-#define F3(x,y,z) (0xca62c1d6 + ((x) ^ (y) ^ (z)))
-
-void
-_sha1block(uchar *p, ulong len, u32int *s)
-{
- u32int w[16], a, b, c, d, e;
- uchar *end;
-
- /* at this point, we have a multiple of 64 bytes */
- for(end = p+len; p < end;){
- a = s[0];
- b = s[1];
- c = s[2];
- d = s[3];
- e = s[4];
-
-#define STEP(a,b,c,d,e,f,i) \
- if(i < 16) {\
- w[i] = p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3]; \
- p += 4; \
- } else { \
- u32int x = w[(i-3)&15] ^ w[(i-8)&15] ^ w[(i-14)&15] ^ w[(i-16)&15]; \
- w[i&15] = ROTL(x, 1); \
- } \
- e += ROTL(a, 5) + w[i&15] + f(b,c,d); \
- b = ROTL(b, 30);
-
- STEP(a,b,c,d,e,F0,0);
- STEP(e,a,b,c,d,F0,1);
- STEP(d,e,a,b,c,F0,2);
- STEP(c,d,e,a,b,F0,3);
- STEP(b,c,d,e,a,F0,4);
-
- STEP(a,b,c,d,e,F0,5);
- STEP(e,a,b,c,d,F0,6);
- STEP(d,e,a,b,c,F0,7);
- STEP(c,d,e,a,b,F0,8);
- STEP(b,c,d,e,a,F0,9);
-
- STEP(a,b,c,d,e,F0,10);
- STEP(e,a,b,c,d,F0,11);
- STEP(d,e,a,b,c,F0,12);
- STEP(c,d,e,a,b,F0,13);
- STEP(b,c,d,e,a,F0,14);
-
- STEP(a,b,c,d,e,F0,15);
- STEP(e,a,b,c,d,F0,16);
- STEP(d,e,a,b,c,F0,17);
- STEP(c,d,e,a,b,F0,18);
- STEP(b,c,d,e,a,F0,19);
-
- STEP(a,b,c,d,e,F1,20);
- STEP(e,a,b,c,d,F1,21);
- STEP(d,e,a,b,c,F1,22);
- STEP(c,d,e,a,b,F1,23);
- STEP(b,c,d,e,a,F1,24);
-
- STEP(a,b,c,d,e,F1,25);
- STEP(e,a,b,c,d,F1,26);
- STEP(d,e,a,b,c,F1,27);
- STEP(c,d,e,a,b,F1,28);
- STEP(b,c,d,e,a,F1,29);
-
- STEP(a,b,c,d,e,F1,30);
- STEP(e,a,b,c,d,F1,31);
- STEP(d,e,a,b,c,F1,32);
- STEP(c,d,e,a,b,F1,33);
- STEP(b,c,d,e,a,F1,34);
-
- STEP(a,b,c,d,e,F1,35);
- STEP(e,a,b,c,d,F1,36);
- STEP(d,e,a,b,c,F1,37);
- STEP(c,d,e,a,b,F1,38);
- STEP(b,c,d,e,a,F1,39);
-
- STEP(a,b,c,d,e,F2,40);
- STEP(e,a,b,c,d,F2,41);
- STEP(d,e,a,b,c,F2,42);
- STEP(c,d,e,a,b,F2,43);
- STEP(b,c,d,e,a,F2,44);
-
- STEP(a,b,c,d,e,F2,45);
- STEP(e,a,b,c,d,F2,46);
- STEP(d,e,a,b,c,F2,47);
- STEP(c,d,e,a,b,F2,48);
- STEP(b,c,d,e,a,F2,49);
-
- STEP(a,b,c,d,e,F2,50);
- STEP(e,a,b,c,d,F2,51);
- STEP(d,e,a,b,c,F2,52);
- STEP(c,d,e,a,b,F2,53);
- STEP(b,c,d,e,a,F2,54);
-
- STEP(a,b,c,d,e,F2,55);
- STEP(e,a,b,c,d,F2,56);
- STEP(d,e,a,b,c,F2,57);
- STEP(c,d,e,a,b,F2,58);
- STEP(b,c,d,e,a,F2,59);
-
- STEP(a,b,c,d,e,F3,60);
- STEP(e,a,b,c,d,F3,61);
- STEP(d,e,a,b,c,F3,62);
- STEP(c,d,e,a,b,F3,63);
- STEP(b,c,d,e,a,F3,64);
-
- STEP(a,b,c,d,e,F3,65);
- STEP(e,a,b,c,d,F3,66);
- STEP(d,e,a,b,c,F3,67);
- STEP(c,d,e,a,b,F3,68);
- STEP(b,c,d,e,a,F3,69);
-
- STEP(a,b,c,d,e,F3,70);
- STEP(e,a,b,c,d,F3,71);
- STEP(d,e,a,b,c,F3,72);
- STEP(c,d,e,a,b,F3,73);
- STEP(b,c,d,e,a,F3,74);
-
- STEP(a,b,c,d,e,F3,75);
- STEP(e,a,b,c,d,F3,76);
- STEP(d,e,a,b,c,F3,77);
- STEP(c,d,e,a,b,F3,78);
- STEP(b,c,d,e,a,F3,79);
-
- s[0] += a;
- s[1] += b;
- s[2] += c;
- s[3] += d;
- s[4] += e;
- }
-}
--- a/libsec/sha2_128.c
+++ /dev/null
@@ -1,191 +1,0 @@
-/*
- * sha2 128-bit
- */
-#include <u.h>
-#include <libc.h>
-#include <libsec.h>
-
-static void encode64(uchar*, u64int*, ulong);
-static DigestState* sha2_128(uchar *, ulong, uchar *, SHA2_256state *, int);
-
-extern void _sha2block128(uchar*, ulong, u64int*);
-
-/*
- * for sha2_384 and sha2_512, len must be multiple of 128 for all but
- * the last call. There must be room in the input buffer to pad.
- *
- * Note: sha2_384 calls sha2_512block as sha2_384; it just uses a different
- * initial seed to produce a truncated 384b hash result. otherwise
- * it's the same as sha2_512.
- */
-SHA2_384state*
-sha2_384(uchar *p, ulong len, uchar *digest, SHA2_384state *s)
-{
- if(s == nil) {
- s = mallocz(sizeof(*s), 1);
- if(s == nil)
- return nil;
- s->malloced = 1;
- }
- if(s->seeded == 0){
- /*
- * seed the state with the first 64 bits of the fractional
- * parts of the square roots of the 9th thru 16th primes.
- */
- s->bstate[0] = 0xcbbb9d5dc1059ed8LL;
- s->bstate[1] = 0x629a292a367cd507LL;
- s->bstate[2] = 0x9159015a3070dd17LL;
- s->bstate[3] = 0x152fecd8f70e5939LL;
- s->bstate[4] = 0x67332667ffc00b31LL;
- s->bstate[5] = 0x8eb44a8768581511LL;
- s->bstate[6] = 0xdb0c2e0d64f98fa7LL;
- s->bstate[7] = 0x47b5481dbefa4fa4LL;
- s->seeded = 1;
- }
- return sha2_128(p, len, digest, s, SHA2_384dlen);
-}
-
-SHA2_512state*
-sha2_512(uchar *p, ulong len, uchar *digest, SHA2_512state *s)
-{
-
- if(s == nil) {
- s = mallocz(sizeof(*s), 1);
- if(s == nil)
- return nil;
- s->malloced = 1;
- }
- if(s->seeded == 0){
- /*
- * seed the state with the first 64 bits of the fractional
- * parts of the square roots of the first 8 primes 2..19).
- */
- s->bstate[0] = 0x6a09e667f3bcc908LL;
- s->bstate[1] = 0xbb67ae8584caa73bLL;
- s->bstate[2] = 0x3c6ef372fe94f82bLL;
- s->bstate[3] = 0xa54ff53a5f1d36f1LL;
- s->bstate[4] = 0x510e527fade682d1LL;
- s->bstate[5] = 0x9b05688c2b3e6c1fLL;
- s->bstate[6] = 0x1f83d9abfb41bd6bLL;
- s->bstate[7] = 0x5be0cd19137e2179LL;
- s->seeded = 1;
- }
- return sha2_128(p, len, digest, s, SHA2_512dlen);
-}
-
-/* common 128 byte block padding and count code for SHA2_384 and SHA2_512 */
-static DigestState*
-sha2_128(uchar *p, ulong len, uchar *digest, SHA2_512state *s, int dlen)
-{
- int i;
- u64int x[16];
- uchar buf[256];
- uchar *e;
-
- /* fill out the partial 128 byte block from previous calls */
- if(s->blen){
- i = 128 - s->blen;
- if(len < i)
- i = len;
- memmove(s->buf + s->blen, p, i);
- len -= i;
- s->blen += i;
- p += i;
- if(s->blen == 128){
- _sha2block128(s->buf, s->blen, s->bstate);
- s->len += s->blen;
- s->blen = 0;
- }
- }
-
- /* do 128 byte blocks */
- i = len & ~(128-1);
- if(i){
- _sha2block128(p, i, s->bstate);
- s->len += i;
- len -= i;
- p += i;
- }
-
- /* save the left overs if not last call */
- if(digest == 0){
- if(len){
- memmove(s->buf, p, len);
- s->blen += len;
- }
- return s;
- }
-
- /*
- * this is the last time through, pad what's left with 0x80,
- * 0's, and the input count to create a multiple of 128 bytes.
- */
- if(s->blen){
- p = s->buf;
- len = s->blen;
- } else {
- memmove(buf, p, len);
- p = buf;
- }
- s->len += len;
- e = p + len;
- if(len < 112)
- i = 112 - len;
- else
- i = 240 - len;
- memset(e, 0, i);
- *e = 0x80;
- len += i;
-
- /* append the count */
- x[0] = 0; /* assume 32b length, i.e. < 4GB */
- x[1] = s->len<<3;
- encode64(p+len, x, 16);
-
- /* digest the last part */
- _sha2block128(p, len+16, s->bstate);
- s->len += len+16;
-
- /* return result and free state */
- encode64(digest, s->bstate, dlen);
- if(s->malloced == 1)
- free(s);
- return nil;
-}
-
-/*
- * Encodes input (ulong long) into output (uchar).
- * Assumes len is a multiple of 8.
- */
-static void
-encode64(uchar *output, u64int *input, ulong len)
-{
- u64int x;
- uchar *e;
-
- for(e = output + len; output < e;) {
- x = *input++;
- *output++ = x >> 56;
- *output++ = x >> 48;
- *output++ = x >> 40;
- *output++ = x >> 32;
- *output++ = x >> 24;
- *output++ = x >> 16;
- *output++ = x >> 8;
- *output++ = x;
- }
-}
-
-DigestState*
-hmac_sha2_384(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest,
- DigestState *s)
-{
- return hmac_x(p, len, key, klen, digest, s, sha2_384, SHA2_384dlen);
-}
-
-DigestState*
-hmac_sha2_512(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest,
- DigestState *s)
-{
- return hmac_x(p, len, key, klen, digest, s, sha2_512, SHA2_512dlen);
-}
--- a/libsec/sha2_64.c
+++ /dev/null
@@ -1,187 +1,0 @@
-/*
- * sha2 64-bit
- */
-#include <u.h>
-#include <libc.h>
-#include <libsec.h>
-
-static void encode32(uchar*, u32int*, ulong);
-static DigestState* sha2_64(uchar *, ulong, uchar *, SHA2_256state *, int);
-
-extern void _sha2block64(uchar*, ulong, u32int*);
-
-/*
- * for sha2_224 and sha2_256, len must be multiple of 64 for all but
- * the last call. There must be room in the input buffer to pad.
- *
- * Note: sha2_224 calls sha2_256block as sha2_224, just uses different
- * initial seed and produces a 224b hash result. otherwise it's
- * the same as sha2_256.
- */
-
-SHA2_224state*
-sha2_224(uchar *p, ulong len, uchar *digest, SHA2_224state *s)
-{
- if(s == nil) {
- s = mallocz(sizeof(*s), 1);
- if(s == nil)
- return nil;
- s->malloced = 1;
- }
- if(s->seeded == 0){
- /*
- * seed the state with the first 32 bits of the fractional
- * parts of the square roots of the first 8 primes 2..19).
- */
- s->state[0] = 0xc1059ed8;
- s->state[1] = 0x367cd507;
- s->state[2] = 0x3070dd17;
- s->state[3] = 0xf70e5939;
- s->state[4] = 0xffc00b31;
- s->state[5] = 0x68581511;
- s->state[6] = 0x64f98fa7;
- s->state[7] = 0xbefa4fa4;
- s->seeded = 1;
- }
- return sha2_64(p, len, digest, s, SHA2_224dlen);
-}
-
-SHA2_256state*
-sha2_256(uchar *p, ulong len, uchar *digest, SHA2_256state *s)
-{
- if(s == nil) {
- s = mallocz(sizeof(*s), 1);
- if(s == nil)
- return nil;
- s->malloced = 1;
- }
- if(s->seeded == 0){
- /*
- * seed the state with the first 32 bits of the fractional
- * parts of the square roots of the first 8 primes 2..19).
- */
- s->state[0] = 0x6a09e667;
- s->state[1] = 0xbb67ae85;
- s->state[2] = 0x3c6ef372;
- s->state[3] = 0xa54ff53a;
- s->state[4] = 0x510e527f;
- s->state[5] = 0x9b05688c;
- s->state[6] = 0x1f83d9ab;
- s->state[7] = 0x5be0cd19;
- s->seeded = 1;
- }
- return sha2_64(p, len, digest, s, SHA2_256dlen);
-}
-
-/* common 64 byte block padding and count code for SHA2_224 and SHA2_256 */
-static DigestState*
-sha2_64(uchar *p, ulong len, uchar *digest, SHA2_256state *s, int dlen)
-{
- int i;
- u32int x[16];
- uchar buf[128];
- uchar *e;
-
- /* fill out the partial 64 byte block from previous calls */
- if(s->blen){
- i = 64 - s->blen;
- if(len < i)
- i = len;
- memmove(s->buf + s->blen, p, i);
- len -= i;
- s->blen += i;
- p += i;
- if(s->blen == 64){
- _sha2block64(s->buf, s->blen, s->state);
- s->len += s->blen;
- s->blen = 0;
- }
- }
-
- /* do 64 byte blocks */
- i = len & ~(64-1);
- if(i){
- _sha2block64(p, i, s->state);
- s->len += i;
- len -= i;
- p += i;
- }
-
- /* save the left overs if not last call */
- if(digest == 0){
- if(len){
- memmove(s->buf, p, len);
- s->blen += len;
- }
- return s;
- }
-
- /*
- * this is the last time through, pad what's left with 0x80,
- * 0's, and the input count to create a multiple of 64 bytes.
- */
- if(s->blen){
- p = s->buf;
- len = s->blen;
- } else {
- memmove(buf, p, len);
- p = buf;
- }
- s->len += len;
- e = p + len;
- if(len < 56)
- i = 56 - len;
- else
- i = 120 - len;
- memset(e, 0, i);
- *e = 0x80;
- len += i;
-
- /* append the count */
- x[0] = s->len>>29;
- x[1] = s->len<<3;
- encode32(p+len, x, 8);
-
- /* digest the last part */
- _sha2block64(p, len+8, s->state);
- s->len += len+8;
-
- /* return result and free state */
- encode32(digest, s->state, dlen);
- if(s->malloced == 1)
- free(s);
- return nil;
-}
-
-/*
- * Encodes input (ulong) into output (uchar).
- * Assumes len is a multiple of 4.
- */
-static void
-encode32(uchar *output, u32int *input, ulong len)
-{
- u32int x;
- uchar *e;
-
- for(e = output + len; output < e;) {
- x = *input++;
- *output++ = x >> 24;
- *output++ = x >> 16;
- *output++ = x >> 8;
- *output++ = x;
- }
-}
-
-DigestState*
-hmac_sha2_224(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest,
- DigestState *s)
-{
- return hmac_x(p, len, key, klen, digest, s, sha2_224, SHA2_224dlen);
-}
-
-DigestState*
-hmac_sha2_256(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest,
- DigestState *s)
-{
- return hmac_x(p, len, key, klen, digest, s, sha2_256, SHA2_256dlen);
-}
--- a/libsec/sha2block128.c
+++ /dev/null
@@ -1,176 +1,0 @@
-/*
- * sha2_512 block cipher - unrolled version
- *
- * note: the following upper and lower case macro names are distinct
- * and reflect the functions defined in FIPS pub. 180-2.
- */
-
-#include "os.h"
-
-#define ROTR(x,n) (((x) >> (n)) | ((x) << (64-(n))))
-#define sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x) >> 7))
-#define sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x) >> 6))
-#define SIGMA0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
-#define SIGMA1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
-#define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
-#define Maj(x,y,z) (((x) | (y)) & ((z) | ((x) & (y))))
-
-/*
- * first 64 bits of the fractional parts of cube roots of
- * first 80 primes (2..311).
- */
-static u64int K512[80] = {
- 0x428a2f98d728ae22LL, 0x7137449123ef65cdLL, 0xb5c0fbcfec4d3b2fLL, 0xe9b5dba58189dbbcLL,
- 0x3956c25bf348b538LL, 0x59f111f1b605d019LL, 0x923f82a4af194f9bLL, 0xab1c5ed5da6d8118LL,
- 0xd807aa98a3030242LL, 0x12835b0145706fbeLL, 0x243185be4ee4b28cLL, 0x550c7dc3d5ffb4e2LL,
- 0x72be5d74f27b896fLL, 0x80deb1fe3b1696b1LL, 0x9bdc06a725c71235LL, 0xc19bf174cf692694LL,
- 0xe49b69c19ef14ad2LL, 0xefbe4786384f25e3LL, 0x0fc19dc68b8cd5b5LL, 0x240ca1cc77ac9c65LL,
- 0x2de92c6f592b0275LL, 0x4a7484aa6ea6e483LL, 0x5cb0a9dcbd41fbd4LL, 0x76f988da831153b5LL,
- 0x983e5152ee66dfabLL, 0xa831c66d2db43210LL, 0xb00327c898fb213fLL, 0xbf597fc7beef0ee4LL,
- 0xc6e00bf33da88fc2LL, 0xd5a79147930aa725LL, 0x06ca6351e003826fLL, 0x142929670a0e6e70LL,
- 0x27b70a8546d22ffcLL, 0x2e1b21385c26c926LL, 0x4d2c6dfc5ac42aedLL, 0x53380d139d95b3dfLL,
- 0x650a73548baf63deLL, 0x766a0abb3c77b2a8LL, 0x81c2c92e47edaee6LL, 0x92722c851482353bLL,
- 0xa2bfe8a14cf10364LL, 0xa81a664bbc423001LL, 0xc24b8b70d0f89791LL, 0xc76c51a30654be30LL,
- 0xd192e819d6ef5218LL, 0xd69906245565a910LL, 0xf40e35855771202aLL, 0x106aa07032bbd1b8LL,
- 0x19a4c116b8d2d0c8LL, 0x1e376c085141ab53LL, 0x2748774cdf8eeb99LL, 0x34b0bcb5e19b48a8LL,
- 0x391c0cb3c5c95a63LL, 0x4ed8aa4ae3418acbLL, 0x5b9cca4f7763e373LL, 0x682e6ff3d6b2b8a3LL,
- 0x748f82ee5defb2fcLL, 0x78a5636f43172f60LL, 0x84c87814a1f0ab72LL, 0x8cc702081a6439ecLL,
- 0x90befffa23631e28LL, 0xa4506cebde82bde9LL, 0xbef9a3f7b2c67915LL, 0xc67178f2e372532bLL,
- 0xca273eceea26619cLL, 0xd186b8c721c0c207LL, 0xeada7dd6cde0eb1eLL, 0xf57d4f7fee6ed178LL,
- 0x06f067aa72176fbaLL, 0x0a637dc5a2c898a6LL, 0x113f9804bef90daeLL, 0x1b710b35131c471bLL,
- 0x28db77f523047d84LL, 0x32caab7b40c72493LL, 0x3c9ebe0a15c9bebcLL, 0x431d67c49c100d4cLL,
- 0x4cc5d4becb3e42b6LL, 0x597f299cfc657e2aLL, 0x5fcb6fab3ad6faecLL, 0x6c44198c4a475817LL
-};
-
-void
-_sha2block128(uchar *p, ulong len, u64int *s)
-{
- u64int w[16], a, b, c, d, e, f, g, h;
- uchar *end;
-
- /* at this point, we have a multiple of 64 bytes */
- for(end = p+len; p < end;){
- a = s[0];
- b = s[1];
- c = s[2];
- d = s[3];
- e = s[4];
- f = s[5];
- g = s[6];
- h = s[7];
-
-#define STEP(a,b,c,d,e,f,g,h,i) \
- if(i < 16) { \
- w[i] = (u64int)(p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3])<<32 | \
- (p[4]<<24 | p[5]<<16 | p[6]<<8 | p[7]); \
- p += 8; \
- } else { \
- u64int s0, s1; \
- s1 = sigma1(w[(i-2)&15]); \
- s0 = sigma0(w[(i-15)&15]); \
- w[i&15] += s1 + w[(i-7)&15] + s0; \
- } \
- h += SIGMA1(e) + Ch(e,f,g) + K512[i] + w[i&15]; \
- d += h; \
- h += SIGMA0(a) + Maj(a,b,c);
-
- STEP(a,b,c,d,e,f,g,h,0);
- STEP(h,a,b,c,d,e,f,g,1);
- STEP(g,h,a,b,c,d,e,f,2);
- STEP(f,g,h,a,b,c,d,e,3);
- STEP(e,f,g,h,a,b,c,d,4);
- STEP(d,e,f,g,h,a,b,c,5);
- STEP(c,d,e,f,g,h,a,b,6);
- STEP(b,c,d,e,f,g,h,a,7);
-
- STEP(a,b,c,d,e,f,g,h,8);
- STEP(h,a,b,c,d,e,f,g,9);
- STEP(g,h,a,b,c,d,e,f,10);
- STEP(f,g,h,a,b,c,d,e,11);
- STEP(e,f,g,h,a,b,c,d,12);
- STEP(d,e,f,g,h,a,b,c,13);
- STEP(c,d,e,f,g,h,a,b,14);
- STEP(b,c,d,e,f,g,h,a,15);
-
- STEP(a,b,c,d,e,f,g,h,16);
- STEP(h,a,b,c,d,e,f,g,17);
- STEP(g,h,a,b,c,d,e,f,18);
- STEP(f,g,h,a,b,c,d,e,19);
- STEP(e,f,g,h,a,b,c,d,20);
- STEP(d,e,f,g,h,a,b,c,21);
- STEP(c,d,e,f,g,h,a,b,22);
- STEP(b,c,d,e,f,g,h,a,23);
-
- STEP(a,b,c,d,e,f,g,h,24);
- STEP(h,a,b,c,d,e,f,g,25);
- STEP(g,h,a,b,c,d,e,f,26);
- STEP(f,g,h,a,b,c,d,e,27);
- STEP(e,f,g,h,a,b,c,d,28);
- STEP(d,e,f,g,h,a,b,c,29);
- STEP(c,d,e,f,g,h,a,b,30);
- STEP(b,c,d,e,f,g,h,a,31);
-
- STEP(a,b,c,d,e,f,g,h,32);
- STEP(h,a,b,c,d,e,f,g,33);
- STEP(g,h,a,b,c,d,e,f,34);
- STEP(f,g,h,a,b,c,d,e,35);
- STEP(e,f,g,h,a,b,c,d,36);
- STEP(d,e,f,g,h,a,b,c,37);
- STEP(c,d,e,f,g,h,a,b,38);
- STEP(b,c,d,e,f,g,h,a,39);
-
- STEP(a,b,c,d,e,f,g,h,40);
- STEP(h,a,b,c,d,e,f,g,41);
- STEP(g,h,a,b,c,d,e,f,42);
- STEP(f,g,h,a,b,c,d,e,43);
- STEP(e,f,g,h,a,b,c,d,44);
- STEP(d,e,f,g,h,a,b,c,45);
- STEP(c,d,e,f,g,h,a,b,46);
- STEP(b,c,d,e,f,g,h,a,47);
-
- STEP(a,b,c,d,e,f,g,h,48);
- STEP(h,a,b,c,d,e,f,g,49);
- STEP(g,h,a,b,c,d,e,f,50);
- STEP(f,g,h,a,b,c,d,e,51);
- STEP(e,f,g,h,a,b,c,d,52);
- STEP(d,e,f,g,h,a,b,c,53);
- STEP(c,d,e,f,g,h,a,b,54);
- STEP(b,c,d,e,f,g,h,a,55);
-
- STEP(a,b,c,d,e,f,g,h,56);
- STEP(h,a,b,c,d,e,f,g,57);
- STEP(g,h,a,b,c,d,e,f,58);
- STEP(f,g,h,a,b,c,d,e,59);
- STEP(e,f,g,h,a,b,c,d,60);
- STEP(d,e,f,g,h,a,b,c,61);
- STEP(c,d,e,f,g,h,a,b,62);
- STEP(b,c,d,e,f,g,h,a,63);
-
- STEP(a,b,c,d,e,f,g,h,64);
- STEP(h,a,b,c,d,e,f,g,65);
- STEP(g,h,a,b,c,d,e,f,66);
- STEP(f,g,h,a,b,c,d,e,67);
- STEP(e,f,g,h,a,b,c,d,68);
- STEP(d,e,f,g,h,a,b,c,69);
- STEP(c,d,e,f,g,h,a,b,70);
- STEP(b,c,d,e,f,g,h,a,71);
-
- STEP(a,b,c,d,e,f,g,h,72);
- STEP(h,a,b,c,d,e,f,g,73);
- STEP(g,h,a,b,c,d,e,f,74);
- STEP(f,g,h,a,b,c,d,e,75);
- STEP(e,f,g,h,a,b,c,d,76);
- STEP(d,e,f,g,h,a,b,c,77);
- STEP(c,d,e,f,g,h,a,b,78);
- STEP(b,c,d,e,f,g,h,a,79);
-
- s[0] += a;
- s[1] += b;
- s[2] += c;
- s[3] += d;
- s[4] += e;
- s[5] += f;
- s[6] += g;
- s[7] += h;
- }
-}
--- a/libsec/sha2block64.c
+++ /dev/null
@@ -1,150 +1,0 @@
-/*
- * sha2_256 block cipher - unrolled version
- *
- * note: the following upper and lower case macro names are distinct
- * and reflect the functions defined in FIPS pub. 180-2.
- */
-
-#include "os.h"
-
-#define ROTR(x,n) (((x) >> (n)) | ((x) << (32-(n))))
-#define sigma0(x) (ROTR((x),7) ^ ROTR((x),18) ^ ((x) >> 3))
-#define sigma1(x) (ROTR((x),17) ^ ROTR((x),19) ^ ((x) >> 10))
-#define SIGMA0(x) (ROTR((x),2) ^ ROTR((x),13) ^ ROTR((x),22))
-#define SIGMA1(x) (ROTR((x),6) ^ ROTR((x),11) ^ ROTR((x),25))
-#define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
-#define Maj(x,y,z) (((x) | (y)) & ((z) | ((x) & (y))))
-
-/*
- * first 32 bits of the fractional parts of cube roots of
- * first 64 primes (2..311).
- */
-static u32int K256[64] = {
- 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,
- 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
- 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,
- 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
- 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,
- 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
- 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,
- 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
- 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,
- 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
- 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,
- 0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
- 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,
- 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
- 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,
- 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2,
-};
-
-void
-_sha2block64(uchar *p, ulong len, u32int *s)
-{
- u32int w[16], a, b, c, d, e, f, g, h;
- uchar *end;
-
- /* at this point, we have a multiple of 64 bytes */
- for(end = p+len; p < end;){
- a = s[0];
- b = s[1];
- c = s[2];
- d = s[3];
- e = s[4];
- f = s[5];
- g = s[6];
- h = s[7];
-
-#define STEP(a,b,c,d,e,f,g,h,i) \
- if(i < 16) {\
- w[i] = p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3]; \
- p += 4; \
- } else { \
- w[i&15] += sigma1(w[(i-2)&15]) + w[(i-7)&15] + sigma0(w[(i-15)&15]); \
- } \
- h += SIGMA1(e) + Ch(e,f,g) + K256[i] + w[i&15]; \
- d += h; \
- h += SIGMA0(a) + Maj(a,b,c);
-
- STEP(a,b,c,d,e,f,g,h,0);
- STEP(h,a,b,c,d,e,f,g,1);
- STEP(g,h,a,b,c,d,e,f,2);
- STEP(f,g,h,a,b,c,d,e,3);
- STEP(e,f,g,h,a,b,c,d,4);
- STEP(d,e,f,g,h,a,b,c,5);
- STEP(c,d,e,f,g,h,a,b,6);
- STEP(b,c,d,e,f,g,h,a,7);
-
- STEP(a,b,c,d,e,f,g,h,8);
- STEP(h,a,b,c,d,e,f,g,9);
- STEP(g,h,a,b,c,d,e,f,10);
- STEP(f,g,h,a,b,c,d,e,11);
- STEP(e,f,g,h,a,b,c,d,12);
- STEP(d,e,f,g,h,a,b,c,13);
- STEP(c,d,e,f,g,h,a,b,14);
- STEP(b,c,d,e,f,g,h,a,15);
-
- STEP(a,b,c,d,e,f,g,h,16);
- STEP(h,a,b,c,d,e,f,g,17);
- STEP(g,h,a,b,c,d,e,f,18);
- STEP(f,g,h,a,b,c,d,e,19);
- STEP(e,f,g,h,a,b,c,d,20);
- STEP(d,e,f,g,h,a,b,c,21);
- STEP(c,d,e,f,g,h,a,b,22);
- STEP(b,c,d,e,f,g,h,a,23);
-
- STEP(a,b,c,d,e,f,g,h,24);
- STEP(h,a,b,c,d,e,f,g,25);
- STEP(g,h,a,b,c,d,e,f,26);
- STEP(f,g,h,a,b,c,d,e,27);
- STEP(e,f,g,h,a,b,c,d,28);
- STEP(d,e,f,g,h,a,b,c,29);
- STEP(c,d,e,f,g,h,a,b,30);
- STEP(b,c,d,e,f,g,h,a,31);
-
- STEP(a,b,c,d,e,f,g,h,32);
- STEP(h,a,b,c,d,e,f,g,33);
- STEP(g,h,a,b,c,d,e,f,34);
- STEP(f,g,h,a,b,c,d,e,35);
- STEP(e,f,g,h,a,b,c,d,36);
- STEP(d,e,f,g,h,a,b,c,37);
- STEP(c,d,e,f,g,h,a,b,38);
- STEP(b,c,d,e,f,g,h,a,39);
-
- STEP(a,b,c,d,e,f,g,h,40);
- STEP(h,a,b,c,d,e,f,g,41);
- STEP(g,h,a,b,c,d,e,f,42);
- STEP(f,g,h,a,b,c,d,e,43);
- STEP(e,f,g,h,a,b,c,d,44);
- STEP(d,e,f,g,h,a,b,c,45);
- STEP(c,d,e,f,g,h,a,b,46);
- STEP(b,c,d,e,f,g,h,a,47);
-
- STEP(a,b,c,d,e,f,g,h,48);
- STEP(h,a,b,c,d,e,f,g,49);
- STEP(g,h,a,b,c,d,e,f,50);
- STEP(f,g,h,a,b,c,d,e,51);
- STEP(e,f,g,h,a,b,c,d,52);
- STEP(d,e,f,g,h,a,b,c,53);
- STEP(c,d,e,f,g,h,a,b,54);
- STEP(b,c,d,e,f,g,h,a,55);
-
- STEP(a,b,c,d,e,f,g,h,56);
- STEP(h,a,b,c,d,e,f,g,57);
- STEP(g,h,a,b,c,d,e,f,58);
- STEP(f,g,h,a,b,c,d,e,59);
- STEP(e,f,g,h,a,b,c,d,60);
- STEP(d,e,f,g,h,a,b,c,61);
- STEP(c,d,e,f,g,h,a,b,62);
- STEP(b,c,d,e,f,g,h,a,63);
-
- s[0] += a;
- s[1] += b;
- s[2] += c;
- s[3] += d;
- s[4] += e;
- s[5] += f;
- s[6] += g;
- s[7] += h;
- }
-}
--- a/libsec/thumb.c
+++ /dev/null
@@ -1,170 +1,0 @@
-#include "os.h"
-#include <bio.h>
-#include <libsec.h>
-
-enum{ ThumbTab = 1<<10 };
-
-static Thumbprint*
-tablehead(uchar *hash, Thumbprint *table)
-{
- return &table[((hash[0]<<8) + hash[1]) & (ThumbTab-1)];
-}
-
-void
-freeThumbprints(Thumbprint *table)
-{
- Thumbprint *hd, *p, *q;
-
- if(table == nil)
- return;
- for(hd = table; hd < table+ThumbTab; hd++){
- for(p = hd->next; p && p != hd; p = q){
- q = p->next;
- free(p);
- }
- }
- free(table);
-}
-
-int
-okThumbprint(uchar *hash, int len, Thumbprint *table)
-{
- Thumbprint *hd, *p;
-
- if(table == nil)
- return 0;
- hd = tablehead(hash, table);
- for(p = hd->next; p; p = p->next){
- if(p->len == len && memcmp(hash, p->hash, len) == 0)
- return 1;
- if(p == hd)
- break;
- }
- return 0;
-}
-
-int
-okCertificate(uchar *cert, int len, Thumbprint *table)
-{
- uchar hash[SHA2_256dlen];
- char thumb[2*SHA2_256dlen+1];
-
- if(table == nil){
- werrstr("no thumbprints provided");
- return 0;
- }
- if(cert == nil || len <= 0){
- werrstr("no certificate provided");
- return 0;
- }
-
- sha1(cert, len, hash, nil);
- if(okThumbprint(hash, SHA1dlen, table))
- return 1;
-
- sha2_256(cert, len, hash, nil);
- if(okThumbprint(hash, SHA2_256dlen, table))
- return 1;
-
- if(X509digestSPKI(cert, len, sha2_256, hash) < 0)
- return 0;
- if(okThumbprint(hash, SHA2_256dlen, table))
- return 1;
-
- len = enc64(thumb, sizeof(thumb), hash, SHA2_256dlen);
- while(len > 0 && thumb[len-1] == '=')
- len--;
- thumb[len] = '\0';
- werrstr("sha256=%s", thumb);
-
- return 0;
-}
-
-static int
-loadThumbprints(char *file, char *tag, Thumbprint *table, Thumbprint *crltab, int depth)
-{
- Thumbprint *hd, *entry;
- char *line, *field[50];
- uchar hash[SHA2_256dlen];
- Biobuf *bin;
- int len, n;
-
- if(depth > 8){
- werrstr("too many includes, last file %s", file);
- return -1;
- }
- if(access(file, AEXIST) < 0)
- return 0; /* not an error */
- if((bin = Bopen(file, OREAD)) == nil)
- return -1;
- for(; (line = Brdstr(bin, '\n', 1)) != nil; free(line)){
- if(tokenize(line, field, nelem(field)) < 2)
- continue;
- if(strcmp(field[0], "#include") == 0){
- if(loadThumbprints(field[1], tag, table, crltab, depth+1) < 0)
- goto err;
- continue;
- }
- if(strcmp(field[0], tag) != 0)
- continue;
- if(strncmp(field[1], "sha1=", 5) == 0){
- field[1] += 5;
- len = SHA1dlen;
- } else if(strncmp(field[1], "sha256=", 7) == 0){
- field[1] += 7;
- len = SHA2_256dlen;
- } else {
- continue;
- }
- n = strlen(field[1]);
- if((n != len*2 || dec16(hash, len, field[1], n) != len)
- && dec64(hash, len, field[1], n) != len){
- werrstr("malformed %s entry in %s: %s", tag, file, field[1]);
- goto err;
- }
- if(crltab && okThumbprint(hash, len, crltab))
- continue;
- hd = tablehead(hash, table);
- if(hd->next == nil)
- entry = hd;
- else {
- if((entry = malloc(sizeof(*entry))) == nil)
- goto err;
- entry->next = hd->next;
- }
- hd->next = entry;
- entry->len = len;
- memcpy(entry->hash, hash, len);
- }
- Bterm(bin);
- return 0;
-err:
- free(line);
- Bterm(bin);
- return -1;
-}
-
-Thumbprint *
-initThumbprints(char *ok, char *crl, char *tag)
-{
- Thumbprint *table, *crltab;
-
- table = crltab = nil;
- if(crl){
- if((crltab = malloc(ThumbTab * sizeof(*crltab))) == nil)
- goto err;
- memset(crltab, 0, ThumbTab * sizeof(*crltab));
- if(loadThumbprints(crl, tag, crltab, nil, 0) < 0)
- goto err;
- }
- if((table = malloc(ThumbTab * sizeof(*table))) == nil)
- goto err;
- memset(table, 0, ThumbTab * sizeof(*table));
- if(loadThumbprints(ok, tag, table, crltab, 0) < 0){
- freeThumbprints(table);
- table = nil;
- }
-err:
- freeThumbprints(crltab);
- return table;
-}
--- a/libsec/tlshand.c
+++ /dev/null
@@ -1,3024 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <auth.h>
-#include <mp.h>
-#include <libsec.h>
-
-// The main groups of functions are:
-// client/server - main handshake protocol definition
-// message functions - formating handshake messages
-// cipher choices - catalog of digest and encrypt algorithms
-// security functions - PKCS#1, sslHMAC, session keygen
-// general utility functions - malloc, serialization
-// The handshake protocol builds on the TLS/SSL3 record layer protocol,
-// which is implemented in kernel device #a. See also /lib/rfc/rfc2246.
-
-enum {
- TLSFinishedLen = 12,
- SSL3FinishedLen = MD5dlen+SHA1dlen,
- MaxKeyData = 160, // amount of secret we may need
- MAXdlen = SHA2_512dlen,
- RandomSize = 32,
- MasterSecretSize = 48,
- AQueue = 0,
- AFlush = 1,
-};
-
-typedef struct Bytes{
- int len;
- uchar data[];
-} Bytes;
-
-typedef struct Ints{
- int len;
- int data[];
-} Ints;
-
-typedef struct Algs{
- char *enc;
- char *digest;
- int nsecret;
- int tlsid;
- int ok;
-} Algs;
-
-typedef struct Namedcurve{
- int tlsid;
- void (*init)(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h);
-} Namedcurve;
-
-typedef struct Finished{
- uchar verify[SSL3FinishedLen];
- int n;
-} Finished;
-
-typedef struct HandshakeHash {
- MD5state md5;
- SHAstate sha1;
- SHA2_256state sha2_256;
-} HandshakeHash;
-
-typedef struct TlsSec TlsSec;
-struct TlsSec {
- RSApub *rsapub;
- AuthRpc *rpc; // factotum for rsa private key
- uchar *psk; // pre-shared key
- int psklen;
- int clientVers; // version in ClientHello
- uchar sec[MasterSecretSize]; // master secret
- uchar srandom[RandomSize]; // server random
- uchar crandom[RandomSize]; // client random
-
- Namedcurve *nc; // selected curve for ECDHE
- // diffie hellman state
- DHstate dh;
- struct {
- ECdomain dom;
- ECpriv Q;
- } ec;
- uchar X[32];
-
- // byte generation and handshake checksum
- void (*prf)(uchar*, int, uchar*, int, char*, uchar*, int);
- void (*setFinished)(TlsSec*, HandshakeHash, uchar*, int);
- int nfin;
-};
-
-typedef struct TlsConnection{
- TlsSec sec[1]; // security management goo
- int hand, ctl; // record layer file descriptors
- int erred; // set when tlsError called
- int (*trace)(char*fmt, ...); // for debugging
- int version; // protocol we are speaking
- Bytes *cert; // server certificate; only last - no chain
-
- int cipher;
- int nsecret; // amount of secret data to init keys
- char *digest; // name of digest algorithm to use
- char *enc; // name of encryption algorithm to use
-
- // for finished messages
- HandshakeHash handhash;
- Finished finished;
-
- uchar *sendp;
- uchar buf[1<<16];
-} TlsConnection;
-
-typedef struct Msg{
- int tag;
- union {
- struct {
- int version;
- uchar random[RandomSize];
- Bytes* sid;
- Ints* ciphers;
- Bytes* compressors;
- Bytes* extensions;
- } clientHello;
- struct {
- int version;
- uchar random[RandomSize];
- Bytes* sid;
- int cipher;
- int compressor;
- Bytes* extensions;
- } serverHello;
- struct {
- int ncert;
- Bytes **certs;
- } certificate;
- struct {
- Bytes *types;
- Ints *sigalgs;
- int nca;
- Bytes **cas;
- } certificateRequest;
- struct {
- Bytes *pskid;
- Bytes *key;
- } clientKeyExchange;
- struct {
- Bytes *pskid;
- Bytes *dh_p;
- Bytes *dh_g;
- Bytes *dh_Ys;
- Bytes *dh_parameters;
- Bytes *dh_signature;
- int sigalg;
- int curve;
- } serverKeyExchange;
- struct {
- int sigalg;
- Bytes *signature;
- } certificateVerify;
- Finished finished;
- } u;
-} Msg;
-
-
-enum {
- SSL3Version = 0x0300,
- TLS10Version = 0x0301,
- TLS11Version = 0x0302,
- TLS12Version = 0x0303,
- ProtocolVersion = TLS12Version, // maximum version we speak
- MinProtoVersion = 0x0300, // limits on version we accept
- MaxProtoVersion = 0x03ff,
-};
-
-// handshake type
-enum {
- HHelloRequest,
- HClientHello,
- HServerHello,
- HSSL2ClientHello = 9, /* local convention; see devtls.c */
- HCertificate = 11,
- HServerKeyExchange,
- HCertificateRequest,
- HServerHelloDone,
- HCertificateVerify,
- HClientKeyExchange,
- HFinished = 20,
- HMax
-};
-
-// alerts
-enum {
- ECloseNotify = 0,
- EUnexpectedMessage = 10,
- EBadRecordMac = 20,
- EDecryptionFailed = 21,
- ERecordOverflow = 22,
- EDecompressionFailure = 30,
- EHandshakeFailure = 40,
- ENoCertificate = 41,
- EBadCertificate = 42,
- EUnsupportedCertificate = 43,
- ECertificateRevoked = 44,
- ECertificateExpired = 45,
- ECertificateUnknown = 46,
- EIllegalParameter = 47,
- EUnknownCa = 48,
- EAccessDenied = 49,
- EDecodeError = 50,
- EDecryptError = 51,
- EExportRestriction = 60,
- EProtocolVersion = 70,
- EInsufficientSecurity = 71,
- EInternalError = 80,
- EInappropriateFallback = 86,
- EUserCanceled = 90,
- ENoRenegotiation = 100,
- EUnknownPSKidentity = 115,
- EMax = 256
-};
-
-// cipher suites
-enum {
- TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0X000A,
- TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0X0016,
-
- TLS_RSA_WITH_AES_128_CBC_SHA = 0X002F,
- TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0X0033,
- TLS_RSA_WITH_AES_256_CBC_SHA = 0X0035,
- TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0X0039,
- TLS_RSA_WITH_AES_128_CBC_SHA256 = 0X003C,
- TLS_RSA_WITH_AES_256_CBC_SHA256 = 0X003D,
- TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0X0067,
-
- TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C,
- TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E,
-
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013,
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014,
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023,
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027,
-
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B,
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F,
-
- GOOGLE_ECDHE_RSA_WITH_CHACHA20_POLY1305 = 0xCC13,
- GOOGLE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = 0xCC14,
- GOOGLE_DHE_RSA_WITH_CHACHA20_POLY1305 = 0xCC15,
-
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 = 0xCCA8,
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = 0xCCA9,
- TLS_DHE_RSA_WITH_CHACHA20_POLY1305 = 0xCCAA,
-
- TLS_PSK_WITH_CHACHA20_POLY1305 = 0xCCAB,
- TLS_PSK_WITH_AES_128_CBC_SHA256 = 0x00AE,
- TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C,
-
- TLS_FALLBACK_SCSV = 0x5600,
-};
-
-// compression methods
-enum {
- CompressionNull = 0,
- CompressionMax
-};
-
-
-// curves
-enum {
- X25519 = 0x001d,
-};
-
-// extensions
-enum {
- Extsni = 0x0000,
- Extec = 0x000a,
- Extecp = 0x000b,
- Extsigalgs = 0x000d,
-};
-
-static Algs cipherAlgs[] = {
- // ECDHE-ECDSA
- {"ccpoly96_aead", "clear", 2*(32+12), TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305},
- {"ccpoly64_aead", "clear", 2*32, GOOGLE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305},
- {"aes_128_gcm_aead", "clear", 2*(16+4), TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
- {"aes_128_cbc", "sha256", 2*(16+16+SHA2_256dlen), TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
-
- // ECDHE-RSA
- {"ccpoly96_aead", "clear", 2*(32+12), TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305},
- {"ccpoly64_aead", "clear", 2*32, GOOGLE_ECDHE_RSA_WITH_CHACHA20_POLY1305},
- {"aes_128_gcm_aead", "clear", 2*(16+4), TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- {"aes_128_cbc", "sha256", 2*(16+16+SHA2_256dlen), TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
- {"aes_128_cbc", "sha1", 2*(16+16+SHA1dlen), TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
- {"aes_256_cbc", "sha1", 2*(32+16+SHA1dlen), TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
-
- // DHE-RSA
- {"ccpoly96_aead", "clear", 2*(32+12), TLS_DHE_RSA_WITH_CHACHA20_POLY1305},
- {"ccpoly64_aead", "clear", 2*32, GOOGLE_DHE_RSA_WITH_CHACHA20_POLY1305},
- {"aes_128_gcm_aead", "clear", 2*(16+4), TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
- {"aes_128_cbc", "sha256", 2*(16+16+SHA2_256dlen), TLS_DHE_RSA_WITH_AES_128_CBC_SHA256},
- {"aes_128_cbc", "sha1", 2*(16+16+SHA1dlen), TLS_DHE_RSA_WITH_AES_128_CBC_SHA},
- {"aes_256_cbc", "sha1", 2*(32+16+SHA1dlen), TLS_DHE_RSA_WITH_AES_256_CBC_SHA},
- {"3des_ede_cbc","sha1", 2*(4*8+SHA1dlen), TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA},
-
- // RSA
- {"aes_128_gcm_aead", "clear", 2*(16+4), TLS_RSA_WITH_AES_128_GCM_SHA256},
- {"aes_128_cbc", "sha256", 2*(16+16+SHA2_256dlen), TLS_RSA_WITH_AES_128_CBC_SHA256},
- {"aes_256_cbc", "sha256", 2*(32+16+SHA2_256dlen), TLS_RSA_WITH_AES_256_CBC_SHA256},
- {"aes_128_cbc", "sha1", 2*(16+16+SHA1dlen), TLS_RSA_WITH_AES_128_CBC_SHA},
- {"aes_256_cbc", "sha1", 2*(32+16+SHA1dlen), TLS_RSA_WITH_AES_256_CBC_SHA},
- {"3des_ede_cbc","sha1", 2*(4*8+SHA1dlen), TLS_RSA_WITH_3DES_EDE_CBC_SHA},
-
- // PSK
- {"ccpoly96_aead", "clear", 2*(32+12), TLS_PSK_WITH_CHACHA20_POLY1305},
- {"aes_128_cbc", "sha256", 2*(16+16+SHA2_256dlen), TLS_PSK_WITH_AES_128_CBC_SHA256},
- {"aes_128_cbc", "sha1", 2*(16+16+SHA1dlen), TLS_PSK_WITH_AES_128_CBC_SHA},
-};
-
-static uchar compressors[] = {
- CompressionNull,
-};
-
-static Namedcurve namedcurves[] = {
- X25519, nil,
- 0x0017, secp256r1,
- 0x0018, secp384r1,
-};
-
-static uchar pointformats[] = {
- CompressionNull /* support of uncompressed point format is mandatory */
-};
-
-static struct {
- DigestState* (*fun)(uchar*, ulong, uchar*, DigestState*);
- int len;
-} hashfun[] = {
-/* [0x00] is reserved for MD5+SHA1 for < TLS1.2 */
- [0x01] {md5, MD5dlen},
- [0x02] {sha1, SHA1dlen},
- [0x03] {sha2_224, SHA2_224dlen},
- [0x04] {sha2_256, SHA2_256dlen},
- [0x05] {sha2_384, SHA2_384dlen},
- [0x06] {sha2_512, SHA2_512dlen},
-};
-
-// signature algorithms (only RSA and ECDSA at the moment)
-static int sigalgs[] = {
- 0x0603, /* SHA512 ECDSA */
- 0x0503, /* SHA384 ECDSA */
- 0x0403, /* SHA256 ECDSA */
- 0x0203, /* SHA1 ECDSA */
-
- 0x0601, /* SHA512 RSA */
- 0x0501, /* SHA384 RSA */
- 0x0401, /* SHA256 RSA */
- 0x0201, /* SHA1 RSA */
-};
-
-static TlsConnection *tlsServer2(int ctl, int hand,
- uchar *cert, int certlen,
- char *pskid, uchar *psk, int psklen,
- int (*trace)(char*fmt, ...), PEMChain *chain);
-static TlsConnection *tlsClient2(int ctl, int hand,
- uchar *cert, int certlen,
- char *pskid, uchar *psk, int psklen,
- uchar *ext, int extlen, int (*trace)(char*fmt, ...));
-static void msgClear(Msg *m);
-static char* msgPrint(char *buf, int n, Msg *m);
-static int msgRecv(TlsConnection *c, Msg *m);
-static int msgSend(TlsConnection *c, Msg *m, int act);
-static void tlsError(TlsConnection *c, int err, char *msg, ...);
-static int setVersion(TlsConnection *c, int version);
-static int setSecrets(TlsConnection *c, int isclient);
-static int finishedMatch(TlsConnection *c, Finished *f);
-static void tlsConnectionFree(TlsConnection *c);
-
-static int isDHE(int tlsid);
-static int isECDHE(int tlsid);
-static int isPSK(int tlsid);
-static int isECDSA(int tlsid);
-
-static int setAlgs(TlsConnection *c, int a);
-static int okCipher(Ints *cv, int ispsk, int canec);
-static int okCompression(Bytes *cv);
-static int initCiphers(void);
-static Ints* makeciphers(int ispsk);
-
-static AuthRpc* factotum_rsa_open(RSApub *rsapub);
-static mpint* factotum_rsa_decrypt(AuthRpc *rpc, mpint *cipher);
-static void factotum_rsa_close(AuthRpc *rpc);
-
-static void tlsSecInits(TlsSec *sec, int cvers, uchar *crandom);
-static int tlsSecRSAs(TlsSec *sec, Bytes *epm);
-static Bytes* tlsSecECDHEs1(TlsSec *sec);
-static int tlsSecECDHEs2(TlsSec *sec, Bytes *Yc);
-static void tlsSecInitc(TlsSec *sec, int cvers);
-static Bytes* tlsSecRSAc(TlsSec *sec, uchar *cert, int ncert);
-static Bytes* tlsSecDHEc(TlsSec *sec, Bytes *p, Bytes *g, Bytes *Ys);
-static Bytes* tlsSecECDHEc(TlsSec *sec, int curve, Bytes *Ys);
-static void tlsSecVers(TlsSec *sec, int v);
-static int tlsSecFinished(TlsSec *sec, HandshakeHash hsh, uchar *fin, int nfin, int isclient);
-static void setMasterSecret(TlsSec *sec, Bytes *pm);
-static int digestDHparams(TlsSec *sec, Bytes *par, uchar digest[MAXdlen], int sigalg);
-static char* verifyDHparams(TlsSec *sec, Bytes *par, Bytes *cert, Bytes *sig, int sigalg);
-
-static Bytes* pkcs1_encrypt(Bytes* data, RSApub* key);
-static Bytes* pkcs1_decrypt(TlsSec *sec, Bytes *data);
-static Bytes* pkcs1_sign(TlsSec *sec, uchar *digest, int digestlen, int sigalg);
-
-static void* emalloc(int);
-static void* erealloc(void*, int);
-static void put32(uchar *p, u32int);
-static void put24(uchar *p, int);
-static void put16(uchar *p, int);
-static int get24(uchar *p);
-static int get16(uchar *p);
-static Bytes* newbytes(int len);
-static Bytes* makebytes(uchar* buf, int len);
-static Bytes* mptobytes(mpint* big, int len);
-static mpint* bytestomp(Bytes* bytes);
-static void freebytes(Bytes* b);
-static Ints* newints(int len);
-static void freeints(Ints* b);
-static int lookupid(Ints* b, int id);
-
-/* x509.c */
-extern mpint* pkcs1padbuf(uchar *buf, int len, mpint *modulus, int blocktype);
-extern int pkcs1unpadbuf(uchar *buf, int len, mpint *modulus, int blocktype);
-extern int asn1encodedigest(DigestState* (*fun)(uchar*, ulong, uchar*, DigestState*), uchar *digest, uchar *buf, int len);
-
-//================= client/server ========================
-
-// push TLS onto fd, returning new (application) file descriptor
-// or -1 if error.
-int
-tlsServer(int fd, TLSconn *conn)
-{
- char buf[8];
- char dname[64];
- uchar seed[2*RandomSize];
- int n, data, ctl, hand;
- TlsConnection *tls;
-
- if(conn == nil)
- return -1;
- ctl = open("#a/tls/clone", ORDWR|OCEXEC);
- if(ctl < 0)
- return -1;
- n = read(ctl, buf, sizeof(buf)-1);
- if(n < 0){
- close(ctl);
- return -1;
- }
- buf[n] = 0;
- snprint(conn->dir, sizeof(conn->dir), "#a/tls/%s", buf);
- snprint(dname, sizeof(dname), "#a/tls/%s/hand", buf);
- hand = open(dname, ORDWR|OCEXEC);
- if(hand < 0){
- close(ctl);
- return -1;
- }
- data = -1;
- fprint(ctl, "fd %d 0x%x", fd, ProtocolVersion);
- tls = tlsServer2(ctl, hand,
- conn->cert, conn->certlen,
- conn->pskID, conn->psk, conn->psklen,
- conn->trace, conn->chain);
- if(tls != nil){
- snprint(dname, sizeof(dname), "#a/tls/%s/data", buf);
- data = open(dname, ORDWR);
- }
- close(hand);
- close(ctl);
- if(data < 0){
- tlsConnectionFree(tls);
- return -1;
- }
- free(conn->cert);
- conn->cert = nil; // client certificates are not yet implemented
- conn->certlen = 0;
- conn->sessionIDlen = 0;
- conn->sessionID = nil;
- if(conn->sessionKey != nil
- && conn->sessionType != nil
- && strcmp(conn->sessionType, "ttls") == 0){
- memmove(seed, tls->sec->crandom, RandomSize);
- memmove(seed+RandomSize, tls->sec->srandom, RandomSize);
- tls->sec->prf(
- conn->sessionKey, conn->sessionKeylen,
- tls->sec->sec, MasterSecretSize,
- conn->sessionConst,
- seed, sizeof(seed));
- }
- tlsConnectionFree(tls);
- close(fd);
- return data;
-}
-
-static uchar*
-tlsClientExtensions(TLSconn *conn, int *plen)
-{
- uchar *b, *p;
- int i, n, m;
-
- p = b = nil;
-
- // RFC6066 - Server Name Identification
- if(conn->serverName != nil && (n = strlen(conn->serverName)) > 0){
- m = p - b;
- b = erealloc(b, m + 2+2+2+1+2+n);
- p = b + m;
-
- put16(p, Extsni), p += 2; /* Type: server_name */
- put16(p, 2+1+2+n), p += 2; /* Length */
- put16(p, 1+2+n), p += 2; /* Server Name list length */
- *p++ = 0; /* Server Name Type: host_name */
- put16(p, n), p += 2; /* Server Name length */
- memmove(p, conn->serverName, n);
- p += n;
- }
-
- // Elliptic Curves (also called Supported Groups)
- if(ProtocolVersion >= TLS10Version){
- m = p - b;
- b = erealloc(b, m + 2+2+2+nelem(namedcurves)*2 + 2+2+1+nelem(pointformats));
- p = b + m;
-
- n = nelem(namedcurves);
- put16(p, Extec), p += 2; /* Type: elliptic_curves / supported_groups */
- put16(p, (n+1)*2), p += 2; /* Length */
- put16(p, n*2), p += 2; /* Elliptic Curves Length */
- for(i=0; i < n; i++){ /* Elliptic Curves */
- put16(p, namedcurves[i].tlsid);
- p += 2;
- }
-
- n = nelem(pointformats);
- put16(p, Extecp), p += 2; /* Type: ec_point_formats */
- put16(p, n+1), p += 2; /* Length */
- *p++ = n; /* EC point formats Length */
- for(i=0; i < n; i++) /* EC point formats */
- *p++ = pointformats[i];
- }
-
- // signature algorithms
- if(ProtocolVersion >= TLS12Version){
- n = nelem(sigalgs);
-
- m = p - b;
- b = erealloc(b, m + 2+2+2+n*2);
- p = b + m;
-
- put16(p, Extsigalgs), p += 2;
- put16(p, n*2 + 2), p += 2;
- put16(p, n*2), p += 2;
- for(i=0; i < n; i++){
- put16(p, sigalgs[i]);
- p += 2;
- }
- }
-
- *plen = p - b;
- return b;
-}
-
-// push TLS onto fd, returning new (application) file descriptor
-// or -1 if error.
-int
-tlsClient(int fd, TLSconn *conn)
-{
- char buf[8];
- char dname[64];
- uchar seed[2*RandomSize];
- int n, data, ctl, hand;
- TlsConnection *tls;
- uchar *ext;
-
- if(conn == nil)
- return -1;
- ctl = open("#a/tls/clone", ORDWR|OCEXEC);
- if(ctl < 0)
- return -1;
- n = read(ctl, buf, sizeof(buf)-1);
- if(n < 0){
- close(ctl);
- return -1;
- }
- buf[n] = 0;
- snprint(conn->dir, sizeof(conn->dir), "#a/tls/%s", buf);
- snprint(dname, sizeof(dname), "#a/tls/%s/hand", buf);
- hand = open(dname, ORDWR|OCEXEC);
- if(hand < 0){
- close(ctl);
- return -1;
- }
- snprint(dname, sizeof(dname), "#a/tls/%s/data", buf);
- data = open(dname, ORDWR);
- if(data < 0){
- close(hand);
- close(ctl);
- return -1;
- }
- fprint(ctl, "fd %d 0x%x", fd, ProtocolVersion);
- ext = tlsClientExtensions(conn, &n);
- tls = tlsClient2(ctl, hand,
- conn->cert, conn->certlen,
- conn->pskID, conn->psk, conn->psklen,
- ext, n, conn->trace);
- free(ext);
- close(hand);
- close(ctl);
- if(tls == nil){
- close(data);
- return -1;
- }
- free(conn->cert);
- if(tls->cert != nil){
- conn->certlen = tls->cert->len;
- conn->cert = emalloc(conn->certlen);
- memcpy(conn->cert, tls->cert->data, conn->certlen);
- } else {
- conn->certlen = 0;
- conn->cert = nil;
- }
- conn->sessionIDlen = 0;
- conn->sessionID = nil;
- if(conn->sessionKey != nil
- && conn->sessionType != nil
- && strcmp(conn->sessionType, "ttls") == 0){
- memmove(seed, tls->sec->crandom, RandomSize);
- memmove(seed+RandomSize, tls->sec->srandom, RandomSize);
- tls->sec->prf(
- conn->sessionKey, conn->sessionKeylen,
- tls->sec->sec, MasterSecretSize,
- conn->sessionConst,
- seed, sizeof(seed));
- }
- tlsConnectionFree(tls);
- close(fd);
- return data;
-}
-
-static int
-countchain(PEMChain *p)
-{
- int i = 0;
-
- while (p) {
- i++;
- p = p->next;
- }
- return i;
-}
-
-static int
-checkClientExtensions(TlsConnection *c, Bytes *ext)
-{
- uchar *p, *e;
- int i, j, n;
-
- if(ext == nil)
- return 0;
-
- for(p = ext->data, e = p+ext->len; p < e; p += n){
- if(e-p < 4)
- goto Short;
- p += 4;
- if(e-p < (n = get16(p-2)))
- goto Short;
- switch(get16(p-4)){
- case Extec:
- if(n < 4 || n % 2 || get16(p) != (n -= 2))
- goto Short;
- p += 2;
- for(i = 0; i < nelem(namedcurves) && c->sec->nc == nil; i++)
- for(j = 0; j < n; j += 2)
- if(namedcurves[i].tlsid == get16(p+j)){
- c->sec->nc = &namedcurves[i];
- break;
- }
- break;
- }
- }
-
- return 0;
-Short:
- tlsError(c, EDecodeError, "clienthello extensions has invalid length");
- return -1;
-}
-
-static TlsConnection *
-tlsServer2(int ctl, int hand,
- uchar *cert, int certlen,
- char *pskid, uchar *psk, int psklen,
- int (*trace)(char*fmt, ...), PEMChain *chp)
-{
- int cipher, compressor, numcerts, i;
- TlsConnection *c;
- Msg m;
-
- if(trace)
- trace("tlsServer2\n");
- if(!initCiphers())
- return nil;
-
- c = emalloc(sizeof(TlsConnection));
- c->ctl = ctl;
- c->hand = hand;
- c->trace = trace;
- c->version = ProtocolVersion;
- c->sendp = c->buf;
-
- memset(&m, 0, sizeof(m));
- if(!msgRecv(c, &m)){
- if(trace)
- trace("initial msgRecv failed\n");
- goto Err;
- }
- if(m.tag != HClientHello) {
- tlsError(c, EUnexpectedMessage, "expected a client hello");
- goto Err;
- }
- if(trace)
- trace("ClientHello version %x\n", m.u.clientHello.version);
- if(setVersion(c, m.u.clientHello.version) < 0) {
- tlsError(c, EIllegalParameter, "incompatible version");
- goto Err;
- }
- if(c->version < ProtocolVersion
- && lookupid(m.u.clientHello.ciphers, TLS_FALLBACK_SCSV) >= 0){
- tlsError(c, EInappropriateFallback, "inappropriate fallback");
- goto Err;
- }
- tlsSecInits(c->sec, m.u.clientHello.version, m.u.clientHello.random);
- tlsSecVers(c->sec, c->version);
- if(psklen > 0){
- c->sec->psk = psk;
- c->sec->psklen = psklen;
- }
- if(certlen > 0){
- /* server certificate */
- c->sec->rsapub = X509toRSApub(cert, certlen, nil, 0);
- if(c->sec->rsapub == nil){
- tlsError(c, EHandshakeFailure, "invalid X509/rsa certificate");
- goto Err;
- }
- c->sec->rpc = factotum_rsa_open(c->sec->rsapub);
- if(c->sec->rpc == nil){
- tlsError(c, EHandshakeFailure, "factotum_rsa_open: %r");
- goto Err;
- }
- }
- if(checkClientExtensions(c, m.u.clientHello.extensions) < 0)
- goto Err;
- cipher = okCipher(m.u.clientHello.ciphers, psklen > 0, c->sec->nc != nil);
- if(cipher < 0 || !setAlgs(c, cipher)) {
- tlsError(c, EHandshakeFailure, "no matching cipher suite");
- goto Err;
- }
- compressor = okCompression(m.u.clientHello.compressors);
- if(compressor < 0) {
- tlsError(c, EHandshakeFailure, "no matching compressor");
- goto Err;
- }
- if(trace)
- trace(" cipher %x, compressor %x\n", cipher, compressor);
- msgClear(&m);
-
- m.tag = HServerHello;
- m.u.serverHello.version = c->version;
- memmove(m.u.serverHello.random, c->sec->srandom, RandomSize);
- m.u.serverHello.cipher = cipher;
- m.u.serverHello.compressor = compressor;
- m.u.serverHello.sid = makebytes(nil, 0);
- if(!msgSend(c, &m, AQueue))
- goto Err;
-
- if(certlen > 0){
- m.tag = HCertificate;
- numcerts = countchain(chp);
- m.u.certificate.ncert = 1 + numcerts;
- m.u.certificate.certs = emalloc(m.u.certificate.ncert * sizeof(Bytes*));
- m.u.certificate.certs[0] = makebytes(cert, certlen);
- for (i = 0; i < numcerts && chp; i++, chp = chp->next)
- m.u.certificate.certs[i+1] = makebytes(chp->pem, chp->pemlen);
- if(!msgSend(c, &m, AQueue))
- goto Err;
- }
-
- if(isECDHE(cipher)){
- m.tag = HServerKeyExchange;
- m.u.serverKeyExchange.curve = c->sec->nc->tlsid;
- m.u.serverKeyExchange.dh_parameters = tlsSecECDHEs1(c->sec);
- if(m.u.serverKeyExchange.dh_parameters == nil){
- tlsError(c, EInternalError, "can't set DH parameters");
- goto Err;
- }
-
- /* sign the DH parameters */
- if(certlen > 0){
- uchar digest[MAXdlen];
- int digestlen;
-
- if(c->version >= TLS12Version)
- m.u.serverKeyExchange.sigalg = 0x0401; /* RSA SHA256 */
- digestlen = digestDHparams(c->sec, m.u.serverKeyExchange.dh_parameters,
- digest, m.u.serverKeyExchange.sigalg);
- if((m.u.serverKeyExchange.dh_signature = pkcs1_sign(c->sec, digest, digestlen,
- m.u.serverKeyExchange.sigalg)) == nil){
- tlsError(c, EHandshakeFailure, "pkcs1_sign: %r");
- goto Err;
- }
- }
- if(!msgSend(c, &m, AQueue))
- goto Err;
- }
-
- m.tag = HServerHelloDone;
- if(!msgSend(c, &m, AFlush))
- goto Err;
-
- if(!msgRecv(c, &m))
- goto Err;
- if(m.tag != HClientKeyExchange) {
- tlsError(c, EUnexpectedMessage, "expected a client key exchange");
- goto Err;
- }
- if(pskid != nil){
- if(m.u.clientKeyExchange.pskid == nil
- || m.u.clientKeyExchange.pskid->len != strlen(pskid)
- || memcmp(pskid, m.u.clientKeyExchange.pskid->data, m.u.clientKeyExchange.pskid->len) != 0){
- tlsError(c, EUnknownPSKidentity, "unknown or missing pskid");
- goto Err;
- }
- }
- if(isECDHE(cipher)){
- if(tlsSecECDHEs2(c->sec, m.u.clientKeyExchange.key) < 0){
- tlsError(c, EHandshakeFailure, "couldn't set keys: %r");
- goto Err;
- }
- } else if(certlen > 0){
- if(tlsSecRSAs(c->sec, m.u.clientKeyExchange.key) < 0){
- tlsError(c, EHandshakeFailure, "couldn't set keys: %r");
- goto Err;
- }
- } else if(psklen > 0){
- setMasterSecret(c->sec, newbytes(psklen));
- } else {
- tlsError(c, EInternalError, "no psk or certificate");
- goto Err;
- }
-
- if(trace)
- trace("tls secrets\n");
- if(setSecrets(c, 0) < 0){
- tlsError(c, EHandshakeFailure, "can't set secrets: %r");
- goto Err;
- }
-
- /* no CertificateVerify; skip to Finished */
- if(tlsSecFinished(c->sec, c->handhash, c->finished.verify, c->finished.n, 1) < 0){
- tlsError(c, EInternalError, "can't set finished: %r");
- goto Err;
- }
- if(!msgRecv(c, &m))
- goto Err;
- if(m.tag != HFinished) {
- tlsError(c, EUnexpectedMessage, "expected a finished");
- goto Err;
- }
- if(!finishedMatch(c, &m.u.finished)) {
- tlsError(c, EHandshakeFailure, "finished verification failed");
- goto Err;
- }
- msgClear(&m);
-
- /* change cipher spec */
- if(fprint(c->ctl, "changecipher") < 0){
- tlsError(c, EInternalError, "can't enable cipher: %r");
- goto Err;
- }
-
- if(tlsSecFinished(c->sec, c->handhash, c->finished.verify, c->finished.n, 0) < 0){
- tlsError(c, EInternalError, "can't set finished: %r");
- goto Err;
- }
- m.tag = HFinished;
- m.u.finished = c->finished;
- if(!msgSend(c, &m, AFlush))
- goto Err;
- if(trace)
- trace("tls finished\n");
-
- if(fprint(c->ctl, "opened") < 0)
- goto Err;
- return c;
-
-Err:
- msgClear(&m);
- tlsConnectionFree(c);
- return nil;
-}
-
-static Bytes*
-tlsSecDHEc(TlsSec *sec, Bytes *p, Bytes *g, Bytes *Ys)
-{
- DHstate *dh = &sec->dh;
- mpint *G, *P, *Y, *K;
- Bytes *Yc;
- int n;
-
- if(p == nil || g == nil || Ys == nil)
- return nil;
- // reject dh primes that is susceptible to logjam
- if(p->len <= 1024/8)
- return nil;
- Yc = nil;
- P = bytestomp(p);
- G = bytestomp(g);
- Y = bytestomp(Ys);
- K = nil;
-
- if(dh_new(dh, P, nil, G) == nil)
- goto Out;
- n = (mpsignif(P)+7)/8;
- Yc = mptobytes(dh->y, n);
- K = dh_finish(dh, Y); /* zeros dh */
- if(K == nil){
- freebytes(Yc);
- Yc = nil;
- goto Out;
- }
- setMasterSecret(sec, mptobytes(K, n));
-
-Out:
- mpfree(K);
- mpfree(Y);
- mpfree(G);
- mpfree(P);
-
- return Yc;
-}
-
-static Bytes*
-tlsSecECDHEc(TlsSec *sec, int curve, Bytes *Ys)
-{
- ECdomain *dom = &sec->ec.dom;
- ECpriv *Q = &sec->ec.Q;
- ECpub *pub;
- ECpoint K;
- Namedcurve *nc;
- Bytes *Yc;
- Bytes *Z;
- int n;
-
- if(Ys == nil)
- return nil;
-
- if(curve == X25519){
- if(Ys->len != 32)
- return nil;
- Yc = newbytes(32);
- curve25519_dh_new(sec->X, Yc->data);
- Z = newbytes(32);
- if(!curve25519_dh_finish(sec->X, Ys->data, Z->data)){
- freebytes(Yc);
- freebytes(Z);
- return nil;
- }
- setMasterSecret(sec, Z);
- }else{
- for(nc = namedcurves; nc->tlsid != curve; nc++)
- if(nc == &namedcurves[nelem(namedcurves)])
- return nil;
- ecdominit(dom, nc->init);
- pub = ecdecodepub(dom, Ys->data, Ys->len);
- if(pub == nil)
- return nil;
-
- memset(Q, 0, sizeof(*Q));
- Q->a.x = mpnew(0);
- Q->a.y = mpnew(0);
- Q->d = mpnew(0);
-
- memset(&K, 0, sizeof(K));
- K.x = mpnew(0);
- K.y = mpnew(0);
-
- ecgen(dom, Q);
- ecmul(dom, pub, Q->d, &K);
-
- n = (mpsignif(dom->p)+7)/8;
- setMasterSecret(sec, mptobytes(K.x, n));
- Yc = newbytes(1 + 2*n);
- Yc->len = ecencodepub(dom, &Q->a, Yc->data, Yc->len);
-
- mpfree(K.x);
- mpfree(K.y);
-
- ecpubfree(pub);
- }
- return Yc;
-}
-
-static TlsConnection *
-tlsClient2(int ctl, int hand,
- uchar *cert, int certlen,
- char *pskid, uchar *psk, int psklen,
- uchar *ext, int extlen,
- int (*trace)(char*fmt, ...))
-{
- int creq, dhx, cipher;
- TlsConnection *c;
- Bytes *epm;
- Msg m;
-
- if(!initCiphers())
- return nil;
-
- epm = nil;
- memset(&m, 0, sizeof(m));
- c = emalloc(sizeof(TlsConnection));
-
- c->ctl = ctl;
- c->hand = hand;
- c->trace = trace;
- c->cert = nil;
- c->sendp = c->buf;
-
- c->version = ProtocolVersion;
- tlsSecInitc(c->sec, c->version);
- if(psklen > 0){
- c->sec->psk = psk;
- c->sec->psklen = psklen;
- }
- if(certlen > 0){
- /* client certificate */
- c->sec->rsapub = X509toRSApub(cert, certlen, nil, 0);
- if(c->sec->rsapub == nil){
- tlsError(c, EInternalError, "invalid X509/rsa certificate");
- goto Err;
- }
- c->sec->rpc = factotum_rsa_open(c->sec->rsapub);
- if(c->sec->rpc == nil){
- tlsError(c, EInternalError, "factotum_rsa_open: %r");
- goto Err;
- }
- }
-
- /* client hello */
- m.tag = HClientHello;
- m.u.clientHello.version = c->version;
- memmove(m.u.clientHello.random, c->sec->crandom, RandomSize);
- m.u.clientHello.sid = makebytes(nil, 0);
- m.u.clientHello.ciphers = makeciphers(psklen > 0);
- m.u.clientHello.compressors = makebytes(compressors,sizeof(compressors));
- m.u.clientHello.extensions = makebytes(ext, extlen);
- if(!msgSend(c, &m, AFlush))
- goto Err;
-
- /* server hello */
- if(!msgRecv(c, &m))
- goto Err;
- if(m.tag != HServerHello) {
- tlsError(c, EUnexpectedMessage, "expected a server hello");
- goto Err;
- }
- if(setVersion(c, m.u.serverHello.version) < 0) {
- tlsError(c, EIllegalParameter, "incompatible version: %r");
- goto Err;
- }
- tlsSecVers(c->sec, c->version);
- memmove(c->sec->srandom, m.u.serverHello.random, RandomSize);
-
- cipher = m.u.serverHello.cipher;
- if((psklen > 0) != isPSK(cipher) || !setAlgs(c, cipher)) {
- tlsError(c, EIllegalParameter, "invalid cipher suite");
- goto Err;
- }
- if(m.u.serverHello.compressor != CompressionNull) {
- tlsError(c, EIllegalParameter, "invalid compression");
- goto Err;
- }
- dhx = isDHE(cipher) || isECDHE(cipher);
- if(!msgRecv(c, &m))
- goto Err;
- if(m.tag == HCertificate){
- if(m.u.certificate.ncert < 1) {
- tlsError(c, EIllegalParameter, "runt certificate");
- goto Err;
- }
- c->cert = makebytes(m.u.certificate.certs[0]->data, m.u.certificate.certs[0]->len);
- if(!msgRecv(c, &m))
- goto Err;
- } else if(psklen == 0) {
- tlsError(c, EUnexpectedMessage, "expected a certificate");
- goto Err;
- }
- if(m.tag == HServerKeyExchange) {
- if(dhx){
- char *err = verifyDHparams(c->sec,
- m.u.serverKeyExchange.dh_parameters,
- c->cert,
- m.u.serverKeyExchange.dh_signature,
- c->version<TLS12Version ? 0x01 : m.u.serverKeyExchange.sigalg);
- if(err != nil){
- tlsError(c, EBadCertificate, "can't verify DH parameters: %s", err);
- goto Err;
- }
- if(isECDHE(cipher))
- epm = tlsSecECDHEc(c->sec,
- m.u.serverKeyExchange.curve,
- m.u.serverKeyExchange.dh_Ys);
- else
- epm = tlsSecDHEc(c->sec,
- m.u.serverKeyExchange.dh_p,
- m.u.serverKeyExchange.dh_g,
- m.u.serverKeyExchange.dh_Ys);
- if(epm == nil){
- tlsError(c, EHandshakeFailure, "bad DH parameters");
- goto Err;
- }
- } else if(psklen == 0){
- tlsError(c, EUnexpectedMessage, "got an server key exchange");
- goto Err;
- }
- if(!msgRecv(c, &m))
- goto Err;
- } else if(dhx){
- tlsError(c, EUnexpectedMessage, "expected server key exchange");
- goto Err;
- }
-
- /* certificate request (optional) */
- creq = 0;
- if(m.tag == HCertificateRequest) {
- creq = 1;
- if(!msgRecv(c, &m))
- goto Err;
- }
-
- if(m.tag != HServerHelloDone) {
- tlsError(c, EUnexpectedMessage, "expected a server hello done");
- goto Err;
- }
- msgClear(&m);
-
- if(!dhx){
- if(c->cert != nil){
- epm = tlsSecRSAc(c->sec, c->cert->data, c->cert->len);
- if(epm == nil){
- tlsError(c, EBadCertificate, "bad certificate: %r");
- goto Err;
- }
- } else if(psklen > 0){
- setMasterSecret(c->sec, newbytes(psklen));
- } else {
- tlsError(c, EInternalError, "no psk or certificate");
- goto Err;
- }
- }
-
- if(trace)
- trace("tls secrets\n");
- if(setSecrets(c, 1) < 0){
- tlsError(c, EHandshakeFailure, "can't set secrets: %r");
- goto Err;
- }
-
- if(creq) {
- m.tag = HCertificate;
- if(certlen > 0){
- m.u.certificate.ncert = 1;
- m.u.certificate.certs = emalloc(m.u.certificate.ncert * sizeof(Bytes*));
- m.u.certificate.certs[0] = makebytes(cert, certlen);
- }
- if(!msgSend(c, &m, AFlush))
- goto Err;
- }
-
- /* client key exchange */
- m.tag = HClientKeyExchange;
- if(psklen > 0){
- if(pskid == nil)
- pskid = "";
- m.u.clientKeyExchange.pskid = makebytes((uchar*)pskid, strlen(pskid));
- }
- m.u.clientKeyExchange.key = epm;
- epm = nil;
-
- if(!msgSend(c, &m, AFlush))
- goto Err;
-
- /* certificate verify */
- if(creq && certlen > 0) {
- HandshakeHash hsave;
- uchar digest[MAXdlen];
- int digestlen;
-
- /* save the state for the Finish message */
- hsave = c->handhash;
- if(c->version < TLS12Version){
- md5(nil, 0, digest, &c->handhash.md5);
- sha1(nil, 0, digest+MD5dlen, &c->handhash.sha1);
- digestlen = MD5dlen+SHA1dlen;
- } else {
- m.u.certificateVerify.sigalg = 0x0401; /* RSA SHA256 */
- sha2_256(nil, 0, digest, &c->handhash.sha2_256);
- digestlen = SHA2_256dlen;
- }
- c->handhash = hsave;
-
- if((m.u.certificateVerify.signature = pkcs1_sign(c->sec, digest, digestlen,
- m.u.certificateVerify.sigalg)) == nil){
- tlsError(c, EHandshakeFailure, "pkcs1_sign: %r");
- goto Err;
- }
-
- m.tag = HCertificateVerify;
- if(!msgSend(c, &m, AFlush))
- goto Err;
- }
-
- /* change cipher spec */
- if(fprint(c->ctl, "changecipher") < 0){
- tlsError(c, EInternalError, "can't enable cipher: %r");
- goto Err;
- }
-
- // Cipherchange must occur immediately before Finished to avoid
- // potential hole; see section 4.3 of Wagner Schneier 1996.
- if(tlsSecFinished(c->sec, c->handhash, c->finished.verify, c->finished.n, 1) < 0){
- tlsError(c, EInternalError, "can't set finished 1: %r");
- goto Err;
- }
- m.tag = HFinished;
- m.u.finished = c->finished;
- if(!msgSend(c, &m, AFlush)) {
- tlsError(c, EInternalError, "can't flush after client Finished: %r");
- goto Err;
- }
-
- if(tlsSecFinished(c->sec, c->handhash, c->finished.verify, c->finished.n, 0) < 0){
- tlsError(c, EInternalError, "can't set finished 0: %r");
- goto Err;
- }
- if(!msgRecv(c, &m)) {
- tlsError(c, EInternalError, "can't read server Finished: %r");
- goto Err;
- }
- if(m.tag != HFinished) {
- tlsError(c, EUnexpectedMessage, "expected a Finished msg from server");
- goto Err;
- }
-
- if(!finishedMatch(c, &m.u.finished)) {
- tlsError(c, EHandshakeFailure, "finished verification failed");
- goto Err;
- }
- msgClear(&m);
-
- if(fprint(c->ctl, "opened") < 0){
- if(trace)
- trace("unable to do final open: %r\n");
- goto Err;
- }
- return c;
-
-Err:
- free(epm);
- msgClear(&m);
- tlsConnectionFree(c);
- return nil;
-}
-
-
-//================= message functions ========================
-
-static void
-msgHash(TlsConnection *c, uchar *p, int n)
-{
- md5(p, n, 0, &c->handhash.md5);
- sha1(p, n, 0, &c->handhash.sha1);
- if(c->version >= TLS12Version)
- sha2_256(p, n, 0, &c->handhash.sha2_256);
-}
-
-static int
-msgSend(TlsConnection *c, Msg *m, int act)
-{
- uchar *p, *e; // sendp = start of new message; p = write pointer; e = end pointer
- int n, i;
-
- p = c->sendp;
- e = &c->buf[sizeof(c->buf)];
- if(c->trace)
- c->trace("send %s", msgPrint((char*)p, e - p, m));
-
- p[0] = m->tag; // header - fill in size later
- p += 4;
-
- switch(m->tag) {
- default:
- tlsError(c, EInternalError, "can't encode a %d", m->tag);
- goto Err;
- case HClientHello:
- if(p+2+RandomSize > e)
- goto Overflow;
- put16(p, m->u.clientHello.version), p += 2;
- memmove(p, m->u.clientHello.random, RandomSize);
- p += RandomSize;
-
- if(p+1+(n = m->u.clientHello.sid->len) > e)
- goto Overflow;
- *p++ = n;
- memmove(p, m->u.clientHello.sid->data, n);
- p += n;
-
- if(p+2+(n = m->u.clientHello.ciphers->len) > e)
- goto Overflow;
- put16(p, n*2), p += 2;
- for(i=0; i<n; i++)
- put16(p, m->u.clientHello.ciphers->data[i]), p += 2;
-
- if(p+1+(n = m->u.clientHello.compressors->len) > e)
- goto Overflow;
- *p++ = n;
- memmove(p, m->u.clientHello.compressors->data, n);
- p += n;
-
- if(m->u.clientHello.extensions == nil
- || (n = m->u.clientHello.extensions->len) == 0)
- break;
- if(p+2+n > e)
- goto Overflow;
- put16(p, n), p += 2;
- memmove(p, m->u.clientHello.extensions->data, n);
- p += n;
- break;
- case HServerHello:
- if(p+2+RandomSize > e)
- goto Overflow;
- put16(p, m->u.serverHello.version), p += 2;
- memmove(p, m->u.serverHello.random, RandomSize);
- p += RandomSize;
-
- if(p+1+(n = m->u.serverHello.sid->len) > e)
- goto Overflow;
- *p++ = n;
- memmove(p, m->u.serverHello.sid->data, n);
- p += n;
-
- if(p+2+1 > e)
- goto Overflow;
- put16(p, m->u.serverHello.cipher), p += 2;
- *p++ = m->u.serverHello.compressor;
-
- if(m->u.serverHello.extensions == nil
- || (n = m->u.serverHello.extensions->len) == 0)
- break;
- if(p+2+n > e)
- goto Overflow;
- put16(p, n), p += 2;
- memmove(p, m->u.serverHello.extensions->data, n);
- p += n;
- break;
- case HServerHelloDone:
- break;
- case HCertificate:
- n = 0;
- for(i = 0; i < m->u.certificate.ncert; i++)
- n += 3 + m->u.certificate.certs[i]->len;
- if(p+3+n > e)
- goto Overflow;
- put24(p, n), p += 3;
- for(i = 0; i < m->u.certificate.ncert; i++){
- n = m->u.certificate.certs[i]->len;
- put24(p, n), p += 3;
- memmove(p, m->u.certificate.certs[i]->data, n);
- p += n;
- }
- break;
- case HCertificateVerify:
- if(p+2+2+(n = m->u.certificateVerify.signature->len) > e)
- goto Overflow;
- if(m->u.certificateVerify.sigalg != 0)
- put16(p, m->u.certificateVerify.sigalg), p += 2;
- put16(p, n), p += 2;
- memmove(p, m->u.certificateVerify.signature->data, n);
- p += n;
- break;
- case HServerKeyExchange:
- if(m->u.serverKeyExchange.pskid != nil){
- if(p+2+(n = m->u.serverKeyExchange.pskid->len) > e)
- goto Overflow;
- put16(p, n), p += 2;
- memmove(p, m->u.serverKeyExchange.pskid->data, n);
- p += n;
- }
- if(m->u.serverKeyExchange.dh_parameters == nil)
- break;
- if(p+(n = m->u.serverKeyExchange.dh_parameters->len) > e)
- goto Overflow;
- memmove(p, m->u.serverKeyExchange.dh_parameters->data, n);
- p += n;
- if(m->u.serverKeyExchange.dh_signature == nil)
- break;
- if(p+2+2+(n = m->u.serverKeyExchange.dh_signature->len) > e)
- goto Overflow;
- if(c->version >= TLS12Version)
- put16(p, m->u.serverKeyExchange.sigalg), p += 2;
- put16(p, n), p += 2;
- memmove(p, m->u.serverKeyExchange.dh_signature->data, n);
- p += n;
- break;
- case HClientKeyExchange:
- if(m->u.clientKeyExchange.pskid != nil){
- if(p+2+(n = m->u.clientKeyExchange.pskid->len) > e)
- goto Overflow;
- put16(p, n), p += 2;
- memmove(p, m->u.clientKeyExchange.pskid->data, n);
- p += n;
- }
- if(m->u.clientKeyExchange.key == nil)
- break;
- if(p+2+(n = m->u.clientKeyExchange.key->len) > e)
- goto Overflow;
- if(isECDHE(c->cipher))
- *p++ = n;
- else if(isDHE(c->cipher) || c->version != SSL3Version)
- put16(p, n), p += 2;
- memmove(p, m->u.clientKeyExchange.key->data, n);
- p += n;
- break;
- case HFinished:
- if(p+m->u.finished.n > e)
- goto Overflow;
- memmove(p, m->u.finished.verify, m->u.finished.n);
- p += m->u.finished.n;
- break;
- }
-
- // go back and fill in size
- n = p - c->sendp;
- put24(c->sendp+1, n-4);
-
- // remember hash of Handshake messages
- if(m->tag != HHelloRequest)
- msgHash(c, c->sendp, n);
-
- c->sendp = p;
- if(act == AFlush){
- c->sendp = c->buf;
- if(write(c->hand, c->buf, p - c->buf) < 0){
- fprint(2, "write error: %r\n");
- goto Err;
- }
- }
- msgClear(m);
- return 1;
-Overflow:
- tlsError(c, EInternalError, "not enougth send buffer for message (%d)", m->tag);
-Err:
- msgClear(m);
- return 0;
-}
-
-static uchar*
-tlsReadN(TlsConnection *c, int n)
-{
- uchar *p, *w, *e;
-
- e = &c->buf[sizeof(c->buf)];
- p = e - n;
- if(n > sizeof(c->buf) || p < c->sendp){
- tlsError(c, EDecodeError, "handshake message too long %d", n);
- return nil;
- }
- for(w = p; w < e; w += n)
- if((n = read(c->hand, w, e - w)) <= 0)
- return nil;
- return p;
-}
-
-static int
-msgRecv(TlsConnection *c, Msg *m)
-{
- uchar *p, *s;
- int type, n, nn, i;
-
- msgClear(m);
- for(;;) {
- p = tlsReadN(c, 4);
- if(p == nil)
- return 0;
- type = p[0];
- n = get24(p+1);
-
- if(type != HHelloRequest)
- break;
- if(n != 0) {
- tlsError(c, EDecodeError, "invalid hello request during handshake");
- return 0;
- }
- }
-
- if(type == HSSL2ClientHello){
- /* Cope with an SSL3 ClientHello expressed in SSL2 record format.
- This is sent by some clients that we must interoperate
- with, such as Java's JSSE and Microsoft's Internet Explorer. */
- int nsid, nrandom, nciph;
-
- p = tlsReadN(c, n);
- if(p == nil)
- return 0;
- msgHash(c, p, n);
- m->tag = HClientHello;
- if(n < 22)
- goto Short;
- m->u.clientHello.version = get16(p+1);
- p += 3;
- n -= 3;
- nn = get16(p); /* cipher_spec_len */
- nsid = get16(p + 2);
- nrandom = get16(p + 4);
- p += 6;
- n -= 6;
- if(nsid != 0 /* no sid's, since shouldn't restart using ssl2 header */
- || nrandom < 16 || nn % 3 || n - nrandom < nn)
- goto Err;
- /* ignore ssl2 ciphers and look for {0x00, ssl3 cipher} */
- nciph = 0;
- for(i = 0; i < nn; i += 3)
- if(p[i] == 0)
- nciph++;
- m->u.clientHello.ciphers = newints(nciph);
- nciph = 0;
- for(i = 0; i < nn; i += 3)
- if(p[i] == 0)
- m->u.clientHello.ciphers->data[nciph++] = get16(&p[i + 1]);
- p += nn;
- m->u.clientHello.sid = makebytes(nil, 0);
- if(nrandom > RandomSize)
- nrandom = RandomSize;
- memset(m->u.clientHello.random, 0, RandomSize - nrandom);
- memmove(&m->u.clientHello.random[RandomSize - nrandom], p, nrandom);
- m->u.clientHello.compressors = newbytes(1);
- m->u.clientHello.compressors->data[0] = CompressionNull;
- goto Ok;
- }
- msgHash(c, p, 4);
-
- p = tlsReadN(c, n);
- if(p == nil)
- return 0;
-
- msgHash(c, p, n);
-
- m->tag = type;
-
- switch(type) {
- default:
- tlsError(c, EUnexpectedMessage, "can't decode a %d", type);
- goto Err;
- case HClientHello:
- if(n < 2)
- goto Short;
- m->u.clientHello.version = get16(p);
- p += 2, n -= 2;
-
- if(n < RandomSize)
- goto Short;
- memmove(m->u.clientHello.random, p, RandomSize);
- p += RandomSize, n -= RandomSize;
- if(n < 1 || n < p[0]+1)
- goto Short;
- m->u.clientHello.sid = makebytes(p+1, p[0]);
- p += m->u.clientHello.sid->len+1;
- n -= m->u.clientHello.sid->len+1;
-
- if(n < 2)
- goto Short;
- nn = get16(p);
- p += 2, n -= 2;
-
- if(nn % 2 || n < nn || nn < 2)
- goto Short;
- m->u.clientHello.ciphers = newints(nn >> 1);
- for(i = 0; i < nn; i += 2)
- m->u.clientHello.ciphers->data[i >> 1] = get16(&p[i]);
- p += nn, n -= nn;
-
- if(n < 1 || n < p[0]+1 || p[0] == 0)
- goto Short;
- nn = p[0];
- m->u.clientHello.compressors = makebytes(p+1, nn);
- p += nn + 1, n -= nn + 1;
-
- if(n < 2)
- break;
- nn = get16(p);
- if(nn > n-2)
- goto Short;
- m->u.clientHello.extensions = makebytes(p+2, nn);
- n -= nn + 2;
- break;
- case HServerHello:
- if(n < 2)
- goto Short;
- m->u.serverHello.version = get16(p);
- p += 2, n -= 2;
-
- if(n < RandomSize)
- goto Short;
- memmove(m->u.serverHello.random, p, RandomSize);
- p += RandomSize, n -= RandomSize;
-
- if(n < 1 || n < p[0]+1)
- goto Short;
- m->u.serverHello.sid = makebytes(p+1, p[0]);
- p += m->u.serverHello.sid->len+1;
- n -= m->u.serverHello.sid->len+1;
-
- if(n < 3)
- goto Short;
- m->u.serverHello.cipher = get16(p);
- m->u.serverHello.compressor = p[2];
- p += 3, n -= 3;
-
- if(n < 2)
- break;
- nn = get16(p);
- if(nn > n-2)
- goto Short;
- m->u.serverHello.extensions = makebytes(p+2, nn);
- n -= nn + 2;
- break;
- case HCertificate:
- if(n < 3)
- goto Short;
- nn = get24(p);
- p += 3, n -= 3;
- if(nn == 0 && n > 0)
- goto Short;
- /* certs */
- i = 0;
- while(n > 0) {
- if(n < 3)
- goto Short;
- nn = get24(p);
- p += 3, n -= 3;
- if(nn > n)
- goto Short;
- m->u.certificate.ncert = i+1;
- m->u.certificate.certs = erealloc(m->u.certificate.certs, (i+1)*sizeof(Bytes*));
- m->u.certificate.certs[i] = makebytes(p, nn);
- p += nn, n -= nn;
- i++;
- }
- break;
- case HCertificateRequest:
- if(n < 1)
- goto Short;
- nn = p[0];
- p++, n--;
- if(nn > n)
- goto Short;
- m->u.certificateRequest.types = makebytes(p, nn);
- p += nn, n -= nn;
- if(c->version >= TLS12Version){
- if(n < 2)
- goto Short;
- nn = get16(p);
- p += 2, n -= 2;
- if(nn % 2)
- goto Short;
- m->u.certificateRequest.sigalgs = newints(nn>>1);
- for(i = 0; i < nn; i += 2)
- m->u.certificateRequest.sigalgs->data[i >> 1] = get16(&p[i]);
- p += nn, n -= nn;
-
- }
- if(n < 2)
- goto Short;
- nn = get16(p);
- p += 2, n -= 2;
- /* nn == 0 can happen; yahoo's servers do it */
- if(nn != n)
- goto Short;
- /* cas */
- i = 0;
- while(n > 0) {
- if(n < 2)
- goto Short;
- nn = get16(p);
- p += 2, n -= 2;
- if(nn < 1 || nn > n)
- goto Short;
- m->u.certificateRequest.nca = i+1;
- m->u.certificateRequest.cas = erealloc(
- m->u.certificateRequest.cas, (i+1)*sizeof(Bytes*));
- m->u.certificateRequest.cas[i] = makebytes(p, nn);
- p += nn, n -= nn;
- i++;
- }
- break;
- case HServerHelloDone:
- break;
- case HServerKeyExchange:
- if(isPSK(c->cipher)){
- if(n < 2)
- goto Short;
- nn = get16(p);
- p += 2, n -= 2;
- if(nn > n)
- goto Short;
- m->u.serverKeyExchange.pskid = makebytes(p, nn);
- p += nn, n -= nn;
- if(n == 0)
- break;
- }
- if(n < 2)
- goto Short;
- s = p;
- if(isECDHE(c->cipher)){
- nn = *p;
- p++, n--;
- if(nn != 3 || nn > n) /* not a named curve */
- goto Short;
- nn = get16(p);
- p += 2, n -= 2;
- m->u.serverKeyExchange.curve = nn;
-
- nn = *p++, n--;
- if(nn < 1 || nn > n)
- goto Short;
- m->u.serverKeyExchange.dh_Ys = makebytes(p, nn);
- p += nn, n -= nn;
- }else if(isDHE(c->cipher)){
- nn = get16(p);
- p += 2, n -= 2;
- if(nn < 1 || nn > n)
- goto Short;
- m->u.serverKeyExchange.dh_p = makebytes(p, nn);
- p += nn, n -= nn;
-
- if(n < 2)
- goto Short;
- nn = get16(p);
- p += 2, n -= 2;
- if(nn < 1 || nn > n)
- goto Short;
- m->u.serverKeyExchange.dh_g = makebytes(p, nn);
- p += nn, n -= nn;
-
- if(n < 2)
- goto Short;
- nn = get16(p);
- p += 2, n -= 2;
- if(nn < 1 || nn > n)
- goto Short;
- m->u.serverKeyExchange.dh_Ys = makebytes(p, nn);
- p += nn, n -= nn;
- } else {
- /* should not happen */
- goto Short;
- }
- m->u.serverKeyExchange.dh_parameters = makebytes(s, p - s);
- if(n >= 2){
- m->u.serverKeyExchange.sigalg = 0;
- if(c->version >= TLS12Version){
- m->u.serverKeyExchange.sigalg = get16(p);
- p += 2, n -= 2;
- if(n < 2)
- goto Short;
- }
- nn = get16(p);
- p += 2, n -= 2;
- if(nn > 0 && nn <= n){
- m->u.serverKeyExchange.dh_signature = makebytes(p, nn);
- n -= nn;
- }
- }
- break;
- case HClientKeyExchange:
- if(isPSK(c->cipher)){
- if(n < 2)
- goto Short;
- nn = get16(p);
- p += 2, n -= 2;
- if(nn > n)
- goto Short;
- m->u.clientKeyExchange.pskid = makebytes(p, nn);
- p += nn, n -= nn;
- if(n == 0)
- break;
- }
- if(n < 2)
- goto Short;
- if(isECDHE(c->cipher))
- nn = *p++, n--;
- else if(isDHE(c->cipher) || c->version != SSL3Version)
- nn = get16(p), p += 2, n -= 2;
- else
- nn = n;
- if(n < nn)
- goto Short;
- m->u.clientKeyExchange.key = makebytes(p, nn);
- n -= nn;
- break;
- case HFinished:
- m->u.finished.n = c->finished.n;
- if(n < m->u.finished.n)
- goto Short;
- memmove(m->u.finished.verify, p, m->u.finished.n);
- n -= m->u.finished.n;
- break;
- }
-
- if(n != 0 && type != HClientHello && type != HServerHello)
- goto Short;
-Ok:
- if(c->trace)
- c->trace("recv %s", msgPrint((char*)c->sendp, &c->buf[sizeof(c->buf)] - c->sendp, m));
- return 1;
-Short:
- tlsError(c, EDecodeError, "handshake message (%d) has invalid length", type);
-Err:
- msgClear(m);
- return 0;
-}
-
-static void
-msgClear(Msg *m)
-{
- int i;
-
- switch(m->tag) {
- case HHelloRequest:
- break;
- case HClientHello:
- freebytes(m->u.clientHello.sid);
- freeints(m->u.clientHello.ciphers);
- freebytes(m->u.clientHello.compressors);
- freebytes(m->u.clientHello.extensions);
- break;
- case HServerHello:
- freebytes(m->u.serverHello.sid);
- freebytes(m->u.serverHello.extensions);
- break;
- case HCertificate:
- for(i=0; i<m->u.certificate.ncert; i++)
- freebytes(m->u.certificate.certs[i]);
- free(m->u.certificate.certs);
- break;
- case HCertificateRequest:
- freebytes(m->u.certificateRequest.types);
- freeints(m->u.certificateRequest.sigalgs);
- for(i=0; i<m->u.certificateRequest.nca; i++)
- freebytes(m->u.certificateRequest.cas[i]);
- free(m->u.certificateRequest.cas);
- break;
- case HCertificateVerify:
- freebytes(m->u.certificateVerify.signature);
- break;
- case HServerHelloDone:
- break;
- case HServerKeyExchange:
- freebytes(m->u.serverKeyExchange.pskid);
- freebytes(m->u.serverKeyExchange.dh_p);
- freebytes(m->u.serverKeyExchange.dh_g);
- freebytes(m->u.serverKeyExchange.dh_Ys);
- freebytes(m->u.serverKeyExchange.dh_parameters);
- freebytes(m->u.serverKeyExchange.dh_signature);
- break;
- case HClientKeyExchange:
- freebytes(m->u.clientKeyExchange.pskid);
- freebytes(m->u.clientKeyExchange.key);
- break;
- case HFinished:
- break;
- }
- memset(m, 0, sizeof(Msg));
-}
-
-static char *
-bytesPrint(char *bs, char *be, char *s0, Bytes *b, char *s1)
-{
- int i;
-
- if(s0)
- bs = seprint(bs, be, "%s", s0);
- if(b == nil)
- bs = seprint(bs, be, "nil");
- else {
- bs = seprint(bs, be, "<%d> [ ", b->len);
- for(i=0; i<b->len; i++)
- bs = seprint(bs, be, "%.2x ", b->data[i]);
- bs = seprint(bs, be, "]");
- }
- if(s1)
- bs = seprint(bs, be, "%s", s1);
- return bs;
-}
-
-static char *
-intsPrint(char *bs, char *be, char *s0, Ints *b, char *s1)
-{
- int i;
-
- if(s0)
- bs = seprint(bs, be, "%s", s0);
- if(b == nil)
- bs = seprint(bs, be, "nil");
- else {
- bs = seprint(bs, be, "[ ");
- for(i=0; i<b->len; i++)
- bs = seprint(bs, be, "%x ", b->data[i]);
- bs = seprint(bs, be, "]");
- }
- if(s1)
- bs = seprint(bs, be, "%s", s1);
- return bs;
-}
-
-static char*
-msgPrint(char *buf, int n, Msg *m)
-{
- int i;
- char *bs = buf, *be = buf+n;
-
- switch(m->tag) {
- default:
- bs = seprint(bs, be, "unknown %d\n", m->tag);
- break;
- case HClientHello:
- bs = seprint(bs, be, "ClientHello\n");
- bs = seprint(bs, be, "\tversion: %.4x\n", m->u.clientHello.version);
- bs = seprint(bs, be, "\trandom: ");
- for(i=0; i<RandomSize; i++)
- bs = seprint(bs, be, "%.2x", m->u.clientHello.random[i]);
- bs = seprint(bs, be, "\n");
- bs = bytesPrint(bs, be, "\tsid: ", m->u.clientHello.sid, "\n");
- bs = intsPrint(bs, be, "\tciphers: ", m->u.clientHello.ciphers, "\n");
- bs = bytesPrint(bs, be, "\tcompressors: ", m->u.clientHello.compressors, "\n");
- if(m->u.clientHello.extensions != nil)
- bs = bytesPrint(bs, be, "\textensions: ", m->u.clientHello.extensions, "\n");
- break;
- case HServerHello:
- bs = seprint(bs, be, "ServerHello\n");
- bs = seprint(bs, be, "\tversion: %.4x\n", m->u.serverHello.version);
- bs = seprint(bs, be, "\trandom: ");
- for(i=0; i<RandomSize; i++)
- bs = seprint(bs, be, "%.2x", m->u.serverHello.random[i]);
- bs = seprint(bs, be, "\n");
- bs = bytesPrint(bs, be, "\tsid: ", m->u.serverHello.sid, "\n");
- bs = seprint(bs, be, "\tcipher: %.4x\n", m->u.serverHello.cipher);
- bs = seprint(bs, be, "\tcompressor: %.2x\n", m->u.serverHello.compressor);
- if(m->u.serverHello.extensions != nil)
- bs = bytesPrint(bs, be, "\textensions: ", m->u.serverHello.extensions, "\n");
- break;
- case HCertificate:
- bs = seprint(bs, be, "Certificate\n");
- for(i=0; i<m->u.certificate.ncert; i++)
- bs = bytesPrint(bs, be, "\t", m->u.certificate.certs[i], "\n");
- break;
- case HCertificateRequest:
- bs = seprint(bs, be, "CertificateRequest\n");
- bs = bytesPrint(bs, be, "\ttypes: ", m->u.certificateRequest.types, "\n");
- if(m->u.certificateRequest.sigalgs != nil)
- bs = intsPrint(bs, be, "\tsigalgs: ", m->u.certificateRequest.sigalgs, "\n");
- bs = seprint(bs, be, "\tcertificateauthorities\n");
- for(i=0; i<m->u.certificateRequest.nca; i++)
- bs = bytesPrint(bs, be, "\t\t", m->u.certificateRequest.cas[i], "\n");
- break;
- case HCertificateVerify:
- bs = seprint(bs, be, "HCertificateVerify\n");
- if(m->u.certificateVerify.sigalg != 0)
- bs = seprint(bs, be, "\tsigalg: %.4x\n", m->u.certificateVerify.sigalg);
- bs = bytesPrint(bs, be, "\tsignature: ", m->u.certificateVerify.signature,"\n");
- break;
- case HServerHelloDone:
- bs = seprint(bs, be, "ServerHelloDone\n");
- break;
- case HServerKeyExchange:
- bs = seprint(bs, be, "HServerKeyExchange\n");
- if(m->u.serverKeyExchange.pskid != nil)
- bs = bytesPrint(bs, be, "\tpskid: ", m->u.serverKeyExchange.pskid, "\n");
- if(m->u.serverKeyExchange.dh_parameters == nil)
- break;
- if(m->u.serverKeyExchange.curve != 0){
- bs = seprint(bs, be, "\tcurve: %.4x\n", m->u.serverKeyExchange.curve);
- } else {
- bs = bytesPrint(bs, be, "\tdh_p: ", m->u.serverKeyExchange.dh_p, "\n");
- bs = bytesPrint(bs, be, "\tdh_g: ", m->u.serverKeyExchange.dh_g, "\n");
- }
- bs = bytesPrint(bs, be, "\tdh_Ys: ", m->u.serverKeyExchange.dh_Ys, "\n");
- if(m->u.serverKeyExchange.sigalg != 0)
- bs = seprint(bs, be, "\tsigalg: %.4x\n", m->u.serverKeyExchange.sigalg);
- bs = bytesPrint(bs, be, "\tdh_parameters: ", m->u.serverKeyExchange.dh_parameters, "\n");
- bs = bytesPrint(bs, be, "\tdh_signature: ", m->u.serverKeyExchange.dh_signature, "\n");
- break;
- case HClientKeyExchange:
- bs = seprint(bs, be, "HClientKeyExchange\n");
- if(m->u.clientKeyExchange.pskid != nil)
- bs = bytesPrint(bs, be, "\tpskid: ", m->u.clientKeyExchange.pskid, "\n");
- if(m->u.clientKeyExchange.key != nil)
- bs = bytesPrint(bs, be, "\tkey: ", m->u.clientKeyExchange.key, "\n");
- break;
- case HFinished:
- bs = seprint(bs, be, "HFinished\n");
- for(i=0; i<m->u.finished.n; i++)
- bs = seprint(bs, be, "%.2x", m->u.finished.verify[i]);
- bs = seprint(bs, be, "\n");
- break;
- }
- USED(bs);
- return buf;
-}
-
-static void
-tlsError(TlsConnection *c, int err, char *fmt, ...)
-{
- char msg[512];
- va_list arg;
-
- va_start(arg, fmt);
- vseprint(msg, msg+sizeof(msg), fmt, arg);
- va_end(arg);
- if(c->trace)
- c->trace("tlsError: %s\n", msg);
- if(c->erred)
- fprint(2, "double error: %r, %s", msg);
- else
- errstr(msg, sizeof(msg));
- c->erred = 1;
- fprint(c->ctl, "alert %d", err);
-}
-
-// commit to specific version number
-static int
-setVersion(TlsConnection *c, int version)
-{
- if(version > MaxProtoVersion || version < MinProtoVersion)
- return -1;
- if(version > c->version)
- version = c->version;
- if(version == SSL3Version) {
- c->version = version;
- c->finished.n = SSL3FinishedLen;
- }else {
- c->version = version;
- c->finished.n = TLSFinishedLen;
- }
- return fprint(c->ctl, "version 0x%x", version);
-}
-
-// confirm that received Finished message matches the expected value
-static int
-finishedMatch(TlsConnection *c, Finished *f)
-{
- return tsmemcmp(f->verify, c->finished.verify, f->n) == 0;
-}
-
-// free memory associated with TlsConnection struct
-// (but don't close the TLS channel itself)
-static void
-tlsConnectionFree(TlsConnection *c)
-{
- if(c == nil)
- return;
-
- dh_finish(&c->sec->dh, nil);
-
- mpfree(c->sec->ec.Q.a.x);
- mpfree(c->sec->ec.Q.a.y);
- mpfree(c->sec->ec.Q.d);
- ecdomfree(&c->sec->ec.dom);
-
- factotum_rsa_close(c->sec->rpc);
- rsapubfree(c->sec->rsapub);
- freebytes(c->cert);
-
- memset(c, 0, sizeof(*c));
- free(c);
-}
-
-
-//================= cipher choices ========================
-
-static int
-isDHE(int tlsid)
-{
- switch(tlsid){
- case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
- case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
- case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
- case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
- case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
- case TLS_DHE_RSA_WITH_CHACHA20_POLY1305:
- case GOOGLE_DHE_RSA_WITH_CHACHA20_POLY1305:
- return 1;
- }
- return 0;
-}
-
-static int
-isECDHE(int tlsid)
-{
- switch(tlsid){
- case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:
- case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305:
-
- case GOOGLE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:
- case GOOGLE_ECDHE_RSA_WITH_CHACHA20_POLY1305:
-
- case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
- case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
-
- case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
- case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
- case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
- case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
- return 1;
- }
- return 0;
-}
-
-static int
-isPSK(int tlsid)
-{
- switch(tlsid){
- case TLS_PSK_WITH_CHACHA20_POLY1305:
- case TLS_PSK_WITH_AES_128_CBC_SHA256:
- case TLS_PSK_WITH_AES_128_CBC_SHA:
- return 1;
- }
- return 0;
-}
-
-static int
-isECDSA(int tlsid)
-{
- switch(tlsid){
- case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:
- case GOOGLE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:
- case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
- case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
- return 1;
- }
- return 0;
-}
-
-static int
-setAlgs(TlsConnection *c, int a)
-{
- int i;
-
- for(i = 0; i < nelem(cipherAlgs); i++){
- if(cipherAlgs[i].tlsid == a){
- c->cipher = a;
- c->enc = cipherAlgs[i].enc;
- c->digest = cipherAlgs[i].digest;
- c->nsecret = cipherAlgs[i].nsecret;
- if(c->nsecret > MaxKeyData)
- return 0;
- return 1;
- }
- }
- return 0;
-}
-
-static int
-okCipher(Ints *cv, int ispsk, int canec)
-{
- int i, c;
-
- for(i = 0; i < nelem(cipherAlgs); i++) {
- c = cipherAlgs[i].tlsid;
- if(!cipherAlgs[i].ok || isECDSA(c) || isDHE(c))
- continue;
- if(isPSK(c) != ispsk)
- continue;
- if(isECDHE(c) && !canec)
- continue;
- if(lookupid(cv, c) >= 0)
- return c;
- }
- return -1;
-}
-
-static int
-okCompression(Bytes *cv)
-{
- int i, c;
-
- for(i = 0; i < nelem(compressors); i++) {
- c = compressors[i];
- if(memchr(cv->data, c, cv->len) != nil)
- return c;
- }
- return -1;
-}
-
-static Lock ciphLock;
-static int nciphers;
-
-static int
-initCiphers(void)
-{
- enum {MaxAlgF = 1024, MaxAlgs = 10};
- char s[MaxAlgF], *flds[MaxAlgs];
- int i, j, n, ok;
-
- lock(&ciphLock);
- if(nciphers){
- unlock(&ciphLock);
- return nciphers;
- }
- j = open("#a/tls/encalgs", OREAD|OCEXEC);
- if(j < 0){
- werrstr("can't open #a/tls/encalgs: %r");
- goto out;
- }
- n = read(j, s, MaxAlgF-1);
- close(j);
- if(n <= 0){
- werrstr("nothing in #a/tls/encalgs: %r");
- goto out;
- }
- s[n] = 0;
- n = getfields(s, flds, MaxAlgs, 1, " \t\r\n");
- for(i = 0; i < nelem(cipherAlgs); i++){
- ok = 0;
- for(j = 0; j < n; j++){
- if(strcmp(cipherAlgs[i].enc, flds[j]) == 0){
- ok = 1;
- break;
- }
- }
- cipherAlgs[i].ok = ok;
- }
-
- j = open("#a/tls/hashalgs", OREAD|OCEXEC);
- if(j < 0){
- werrstr("can't open #a/tls/hashalgs: %r");
- goto out;
- }
- n = read(j, s, MaxAlgF-1);
- close(j);
- if(n <= 0){
- werrstr("nothing in #a/tls/hashalgs: %r");
- goto out;
- }
- s[n] = 0;
- n = getfields(s, flds, MaxAlgs, 1, " \t\r\n");
- for(i = 0; i < nelem(cipherAlgs); i++){
- ok = 0;
- for(j = 0; j < n; j++){
- if(strcmp(cipherAlgs[i].digest, flds[j]) == 0){
- ok = 1;
- break;
- }
- }
- cipherAlgs[i].ok &= ok;
- if(cipherAlgs[i].ok)
- nciphers++;
- }
-out:
- unlock(&ciphLock);
- return nciphers;
-}
-
-static Ints*
-makeciphers(int ispsk)
-{
- Ints *is;
- int i, j;
-
- is = newints(nciphers);
- j = 0;
- for(i = 0; i < nelem(cipherAlgs); i++)
- if(cipherAlgs[i].ok && isPSK(cipherAlgs[i].tlsid) == ispsk)
- is->data[j++] = cipherAlgs[i].tlsid;
- is->len = j;
- return is;
-}
-
-
-//================= security functions ========================
-
-// given a public key, set up connection to factotum
-// for using corresponding private key
-static AuthRpc*
-factotum_rsa_open(RSApub *rsapub)
-{
- int afd;
- char *s;
- mpint *n;
- AuthRpc *rpc;
-
- // start talking to factotum
- if((afd = open("/mnt/factotum/rpc", ORDWR|OCEXEC)) < 0)
- return nil;
- if((rpc = auth_allocrpc(afd)) == nil){
- close(afd);
- return nil;
- }
- s = "proto=rsa service=tls role=client";
- if(auth_rpc(rpc, "start", s, strlen(s)) == ARok){
- // roll factotum keyring around to match public key
- n = mpnew(0);
- while(auth_rpc(rpc, "read", nil, 0) == ARok){
- if(strtomp(rpc->arg, nil, 16, n) != nil
- && mpcmp(n, rsapub->n) == 0){
- mpfree(n);
- return rpc;
- }
- }
- mpfree(n);
- }
- factotum_rsa_close(rpc);
- return nil;
-}
-
-static mpint*
-factotum_rsa_decrypt(AuthRpc *rpc, mpint *cipher)
-{
- char *p;
- int rv;
-
- if(cipher == nil)
- return nil;
- p = mptoa(cipher, 16, nil, 0);
- mpfree(cipher);
- if(p == nil)
- return nil;
- rv = auth_rpc(rpc, "write", p, strlen(p));
- free(p);
- if(rv != ARok || auth_rpc(rpc, "read", nil, 0) != ARok)
- return nil;
- return strtomp(rpc->arg, nil, 16, nil);
-}
-
-static void
-factotum_rsa_close(AuthRpc *rpc)
-{
- if(rpc == nil)
- return;
- close(rpc->afd);
- auth_freerpc(rpc);
-}
-
-// buf ^= prf
-static void
-tlsP(uchar *buf, int nbuf, uchar *key, int nkey, uchar *label, int nlabel, uchar *seed, int nseed,
- DigestState* (*x)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*), int xlen)
-{
- uchar ai[SHA2_256dlen], tmp[SHA2_256dlen];
- DigestState *s;
- int n, i;
-
- assert(xlen <= sizeof(ai) && xlen <= sizeof(tmp));
- // generate a1
- s = x(label, nlabel, key, nkey, nil, nil);
- x(seed, nseed, key, nkey, ai, s);
-
- while(nbuf > 0) {
- s = x(ai, xlen, key, nkey, nil, nil);
- s = x(label, nlabel, key, nkey, nil, s);
- x(seed, nseed, key, nkey, tmp, s);
- n = xlen;
- if(n > nbuf)
- n = nbuf;
- for(i = 0; i < n; i++)
- buf[i] ^= tmp[i];
- buf += n;
- nbuf -= n;
- x(ai, xlen, key, nkey, tmp, nil);
- memmove(ai, tmp, xlen);
- }
-}
-
-
-// fill buf with md5(args)^sha1(args)
-static void
-tls10PRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed, int nseed)
-{
- int nlabel = strlen(label);
- int n = (nkey + 1) >> 1;
-
- memset(buf, 0, nbuf);
- tlsP(buf, nbuf, key, n, (uchar*)label, nlabel, seed, nseed,
- hmac_md5, MD5dlen);
- tlsP(buf, nbuf, key+nkey-n, n, (uchar*)label, nlabel, seed, nseed,
- hmac_sha1, SHA1dlen);
-}
-
-static void
-tls12PRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed, int nseed)
-{
- memset(buf, 0, nbuf);
- tlsP(buf, nbuf, key, nkey, (uchar*)label, strlen(label), seed, nseed,
- hmac_sha2_256, SHA2_256dlen);
-}
-
-static void
-sslPRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed, int nseed)
-{
- uchar sha1dig[SHA1dlen], md5dig[MD5dlen], tmp[26];
- DigestState *s;
- int i, n, len;
-
- USED(label);
- len = 1;
- while(nbuf > 0){
- if(len > 26)
- return;
- for(i = 0; i < len; i++)
- tmp[i] = 'A' - 1 + len;
- s = sha1(tmp, len, nil, nil);
- s = sha1(key, nkey, nil, s);
- sha1(seed, nseed, sha1dig, s);
- s = md5(key, nkey, nil, nil);
- md5(sha1dig, SHA1dlen, md5dig, s);
- n = MD5dlen;
- if(n > nbuf)
- n = nbuf;
- memmove(buf, md5dig, n);
- buf += n;
- nbuf -= n;
- len++;
- }
-}
-
-static void
-sslSetFinished(TlsSec *sec, HandshakeHash hsh, uchar *finished, int isclient)
-{
- DigestState *s;
- uchar h0[MD5dlen], h1[SHA1dlen], pad[48];
- char *label;
-
- if(isclient)
- label = "CLNT";
- else
- label = "SRVR";
-
- md5((uchar*)label, 4, nil, &hsh.md5);
- md5(sec->sec, MasterSecretSize, nil, &hsh.md5);
- memset(pad, 0x36, 48);
- md5(pad, 48, nil, &hsh.md5);
- md5(nil, 0, h0, &hsh.md5);
- memset(pad, 0x5C, 48);
- s = md5(sec->sec, MasterSecretSize, nil, nil);
- s = md5(pad, 48, nil, s);
- md5(h0, MD5dlen, finished, s);
-
- sha1((uchar*)label, 4, nil, &hsh.sha1);
- sha1(sec->sec, MasterSecretSize, nil, &hsh.sha1);
- memset(pad, 0x36, 40);
- sha1(pad, 40, nil, &hsh.sha1);
- sha1(nil, 0, h1, &hsh.sha1);
- memset(pad, 0x5C, 40);
- s = sha1(sec->sec, MasterSecretSize, nil, nil);
- s = sha1(pad, 40, nil, s);
- sha1(h1, SHA1dlen, finished + MD5dlen, s);
-}
-
-// fill "finished" arg with md5(args)^sha1(args)
-static void
-tls10SetFinished(TlsSec *sec, HandshakeHash hsh, uchar *finished, int isclient)
-{
- uchar h[MD5dlen+SHA1dlen];
- char *label;
-
- // get current hash value, but allow further messages to be hashed in
- md5(nil, 0, h, &hsh.md5);
- sha1(nil, 0, h+MD5dlen, &hsh.sha1);
-
- if(isclient)
- label = "client finished";
- else
- label = "server finished";
- tls10PRF(finished, TLSFinishedLen, sec->sec, MasterSecretSize, label, h, sizeof(h));
-}
-
-static void
-tls12SetFinished(TlsSec *sec, HandshakeHash hsh, uchar *finished, int isclient)
-{
- uchar seed[SHA2_256dlen];
- char *label;
-
- // get current hash value, but allow further messages to be hashed in
- sha2_256(nil, 0, seed, &hsh.sha2_256);
-
- if(isclient)
- label = "client finished";
- else
- label = "server finished";
- tls12PRF(finished, TLSFinishedLen, sec->sec, MasterSecretSize, label, seed, SHA2_256dlen);
-}
-
-static void
-tlsSecInits(TlsSec *sec, int cvers, uchar *crandom)
-{
- memset(sec, 0, sizeof(*sec));
- sec->clientVers = cvers;
- memmove(sec->crandom, crandom, RandomSize);
-
- // putting time()'s output to the first 4 bytes is no
- // longer recommended and is not useful
- genrandom(sec->srandom, RandomSize);
-}
-
-static int
-tlsSecRSAs(TlsSec *sec, Bytes *epm)
-{
- Bytes *pm;
-
- if(epm == nil){
- werrstr("no encrypted premaster secret");
- return -1;
- }
- // if the client messed up, just continue as if everything is ok,
- // to prevent attacks to check for correctly formatted messages.
- pm = pkcs1_decrypt(sec, epm);
- if(pm == nil || pm->len != MasterSecretSize || get16(pm->data) != sec->clientVers){
- freebytes(pm);
- pm = newbytes(MasterSecretSize);
- genrandom(pm->data, pm->len);
- }
- setMasterSecret(sec, pm);
- return 0;
-}
-
-static Bytes*
-tlsSecECDHEs1(TlsSec *sec)
-{
- ECdomain *dom = &sec->ec.dom;
- ECpriv *Q = &sec->ec.Q;
- Bytes *par;
- int n;
-
- if(sec->nc == nil)
- return nil;
- if(sec->nc->tlsid == X25519){
- par = newbytes(1+2+1+32);
- par->data[0] = 3;
- put16(par->data+1, X25519);
- par->data[3] = 32;
- curve25519_dh_new(sec->X, par->data+4);
- }else{
- ecdominit(dom, sec->nc->init);
- memset(Q, 0, sizeof(*Q));
- Q->a.x = mpnew(0);
- Q->a.y = mpnew(0);
- Q->d = mpnew(0);
- ecgen(dom, Q);
- n = 1 + 2*((mpsignif(dom->p)+7)/8);
- par = newbytes(1+2+1+n);
- par->data[0] = 3;
- put16(par->data+1, sec->nc->tlsid);
- n = ecencodepub(dom, &Q->a, par->data+4, par->len-4);
- par->data[3] = n;
- par->len = 1+2+1+n;
- }
- return par;
-}
-
-static int
-tlsSecECDHEs2(TlsSec *sec, Bytes *Yc)
-{
- ECdomain *dom = &sec->ec.dom;
- ECpriv *Q = &sec->ec.Q;
- ECpoint K;
- ECpub *Y;
- Bytes *Z;
-
- if(Yc == nil){
- werrstr("no public key");
- return -1;
- }
-
- if(sec->nc->tlsid == X25519){
- if(Yc->len != 32){
- werrstr("bad public key");
- return -1;
- }
- Z = newbytes(32);
- if(!curve25519_dh_finish(sec->X, Yc->data, Z->data)){
- werrstr("unlucky shared key");
- freebytes(Z);
- return -1;
- }
- setMasterSecret(sec, Z);
- }else{
- if((Y = ecdecodepub(dom, Yc->data, Yc->len)) == nil){
- werrstr("bad public key");
- return -1;
- }
-
- memset(&K, 0, sizeof(K));
- K.x = mpnew(0);
- K.y = mpnew(0);
-
- ecmul(dom, Y, Q->d, &K);
-
- setMasterSecret(sec, mptobytes(K.x, (mpsignif(dom->p)+7)/8));
-
- mpfree(K.x);
- mpfree(K.y);
-
- ecpubfree(Y);
- }
- return 0;
-}
-
-static void
-tlsSecInitc(TlsSec *sec, int cvers)
-{
- memset(sec, 0, sizeof(*sec));
- sec->clientVers = cvers;
- // see the comment on tlsSecInits
- genrandom(sec->crandom, RandomSize);
-}
-
-static Bytes*
-tlsSecRSAc(TlsSec *sec, uchar *cert, int ncert)
-{
- RSApub *pub;
- Bytes *pm, *epm;
-
- pub = X509toRSApub(cert, ncert, nil, 0);
- if(pub == nil){
- werrstr("invalid x509/rsa certificate");
- return nil;
- }
- pm = newbytes(MasterSecretSize);
- put16(pm->data, sec->clientVers);
- genrandom(pm->data+2, MasterSecretSize - 2);
- epm = pkcs1_encrypt(pm, pub);
- setMasterSecret(sec, pm);
- rsapubfree(pub);
- return epm;
-}
-
-static int
-tlsSecFinished(TlsSec *sec, HandshakeHash hsh, uchar *fin, int nfin, int isclient)
-{
- if(sec->nfin != nfin){
- werrstr("invalid finished exchange");
- return -1;
- }
- hsh.md5.malloced = 0;
- hsh.sha1.malloced = 0;
- hsh.sha2_256.malloced = 0;
- (*sec->setFinished)(sec, hsh, fin, isclient);
- return 0;
-}
-
-static void
-tlsSecVers(TlsSec *sec, int v)
-{
- if(v == SSL3Version){
- sec->setFinished = sslSetFinished;
- sec->nfin = SSL3FinishedLen;
- sec->prf = sslPRF;
- }else if(v < TLS12Version) {
- sec->setFinished = tls10SetFinished;
- sec->nfin = TLSFinishedLen;
- sec->prf = tls10PRF;
- }else {
- sec->setFinished = tls12SetFinished;
- sec->nfin = TLSFinishedLen;
- sec->prf = tls12PRF;
- }
-}
-
-static int
-setSecrets(TlsConnection *c, int isclient)
-{
- uchar kd[MaxKeyData], seed[2*RandomSize];
- char *secrets;
- int rv;
-
- assert(c->nsecret <= sizeof(kd));
- secrets = emalloc(2*c->nsecret);
-
- memmove(seed, c->sec->srandom, RandomSize);
- memmove(seed+RandomSize, c->sec->crandom, RandomSize);
- /*
- * generate secret keys from the master secret.
- *
- * different cipher selections will require different amounts
- * of key expansion and use of key expansion data,
- * but it's all generated using the same function.
- */
- (*c->sec->prf)(kd, c->nsecret, c->sec->sec, MasterSecretSize, "key expansion",
- seed, sizeof(seed));
-
- enc64(secrets, 2*c->nsecret, kd, c->nsecret);
- memset(kd, 0, c->nsecret);
-
- rv = fprint(c->ctl, "secret %s %s %d %s", c->digest, c->enc, isclient, secrets);
- memset(secrets, 0, 2*c->nsecret);
- free(secrets);
-
- return rv;
-}
-
-/*
- * set the master secret from the pre-master secret,
- * destroys premaster.
- */
-static void
-setMasterSecret(TlsSec *sec, Bytes *pm)
-{
- uchar seed[2*RandomSize];
-
- if(sec->psklen > 0){
- Bytes *opm = pm;
- uchar *p;
-
- /* concatenate psk to pre-master secret */
- pm = newbytes(4 + opm->len + sec->psklen);
- p = pm->data;
- put16(p, opm->len), p += 2;
- memmove(p, opm->data, opm->len), p += opm->len;
- put16(p, sec->psklen), p += 2;
- memmove(p, sec->psk, sec->psklen);
-
- memset(opm->data, 0, opm->len);
- freebytes(opm);
- }
-
- memmove(seed, sec->crandom, RandomSize);
- memmove(seed+RandomSize, sec->srandom, RandomSize);
- (*sec->prf)(sec->sec, MasterSecretSize, pm->data, pm->len, "master secret",
- seed, sizeof(seed));
-
- memset(pm->data, 0, pm->len);
- freebytes(pm);
-}
-
-static int
-digestDHparams(TlsSec *sec, Bytes *par, uchar digest[MAXdlen], int sigalg)
-{
- int hashalg = (sigalg>>8) & 0xFF;
- int digestlen;
- Bytes *blob;
-
- blob = newbytes(2*RandomSize + par->len);
- memmove(blob->data+0*RandomSize, sec->crandom, RandomSize);
- memmove(blob->data+1*RandomSize, sec->srandom, RandomSize);
- memmove(blob->data+2*RandomSize, par->data, par->len);
- if(hashalg == 0){
- digestlen = MD5dlen+SHA1dlen;
- md5(blob->data, blob->len, digest, nil);
- sha1(blob->data, blob->len, digest+MD5dlen, nil);
- } else {
- digestlen = -1;
- if(hashalg < nelem(hashfun) && hashfun[hashalg].fun != nil){
- digestlen = hashfun[hashalg].len;
- (*hashfun[hashalg].fun)(blob->data, blob->len, digest, nil);
- }
- }
- freebytes(blob);
- return digestlen;
-}
-
-static char*
-verifyDHparams(TlsSec *sec, Bytes *par, Bytes *cert, Bytes *sig, int sigalg)
-{
- uchar digest[MAXdlen];
- int digestlen;
- ECdomain dom;
- ECpub *ecpk;
- RSApub *rsapk;
- char *err;
-
- if(par == nil || par->len <= 0)
- return "no DH parameters";
-
- if(sig == nil || sig->len <= 0){
- if(sec->psklen > 0)
- return nil;
- return "no signature";
- }
-
- if(cert == nil)
- return "no certificate";
-
- digestlen = digestDHparams(sec, par, digest, sigalg);
- if(digestlen <= 0)
- return "unknown signature digest algorithm";
-
- switch(sigalg & 0xFF){
- case 0x01:
- rsapk = X509toRSApub(cert->data, cert->len, nil, 0);
- if(rsapk == nil)
- return "bad certificate";
- err = X509rsaverifydigest(sig->data, sig->len, digest, digestlen, rsapk);
- rsapubfree(rsapk);
- break;
- case 0x03:
- ecpk = X509toECpub(cert->data, cert->len, nil, 0, &dom);
- if(ecpk == nil)
- return "bad certificate";
- err = X509ecdsaverifydigest(sig->data, sig->len, digest, digestlen, &dom, ecpk);
- ecdomfree(&dom);
- ecpubfree(ecpk);
- break;
- default:
- err = "signaure algorithm not RSA or ECDSA";
- }
-
- return err;
-}
-
-// encrypt data according to PKCS#1, /lib/rfc/rfc2437 9.1.2.1
-static Bytes*
-pkcs1_encrypt(Bytes* data, RSApub* key)
-{
- mpint *x, *y;
-
- x = pkcs1padbuf(data->data, data->len, key->n, 2);
- if(x == nil)
- return nil;
- y = rsaencrypt(key, x, nil);
- mpfree(x);
- data = newbytes((mpsignif(key->n)+7)/8);
- mptober(y, data->data, data->len);
- mpfree(y);
- return data;
-}
-
-// decrypt data according to PKCS#1, with given key.
-static Bytes*
-pkcs1_decrypt(TlsSec *sec, Bytes *data)
-{
- mpint *y;
-
- if(data->len != (mpsignif(sec->rsapub->n)+7)/8)
- return nil;
- y = factotum_rsa_decrypt(sec->rpc, bytestomp(data));
- if(y == nil)
- return nil;
- data = mptobytes(y, (mpsignif(y)+7)/8);
- mpfree(y);
- if((data->len = pkcs1unpadbuf(data->data, data->len, sec->rsapub->n, 2)) < 0){
- freebytes(data);
- return nil;
- }
- return data;
-}
-
-static Bytes*
-pkcs1_sign(TlsSec *sec, uchar *digest, int digestlen, int sigalg)
-{
- int hashalg = (sigalg>>8)&0xFF;
- mpint *signedMP;
- Bytes *signature;
- uchar buf[128];
-
- if(hashalg > 0 && hashalg < nelem(hashfun) && hashfun[hashalg].len == digestlen)
- digestlen = asn1encodedigest(hashfun[hashalg].fun, digest, buf, sizeof(buf));
- else if(digestlen == MD5dlen+SHA1dlen)
- memmove(buf, digest, digestlen);
- else
- digestlen = -1;
- if(digestlen <= 0){
- werrstr("bad digest algorithm");
- return nil;
- }
-
- signedMP = factotum_rsa_decrypt(sec->rpc, pkcs1padbuf(buf, digestlen, sec->rsapub->n, 1));
- if(signedMP == nil)
- return nil;
- signature = mptobytes(signedMP, (mpsignif(sec->rsapub->n)+7)/8);
- mpfree(signedMP);
- return signature;
-}
-
-
-//================= general utility functions ========================
-
-static void *
-emalloc(int n)
-{
- void *p;
- if(n==0)
- n=1;
- p = malloc(n);
- if(p == nil)
- sysfatal("out of memory");
- memset(p, 0, n);
- setmalloctag(p, getcallerpc(&n));
- return p;
-}
-
-static void *
-erealloc(void *ReallocP, int ReallocN)
-{
- if(ReallocN == 0)
- ReallocN = 1;
- if(ReallocP == nil)
- ReallocP = emalloc(ReallocN);
- else if((ReallocP = realloc(ReallocP, ReallocN)) == nil)
- sysfatal("out of memory");
- setrealloctag(ReallocP, getcallerpc(&ReallocP));
- return(ReallocP);
-}
-
-static void
-put32(uchar *p, u32int x)
-{
- p[0] = x>>24;
- p[1] = x>>16;
- p[2] = x>>8;
- p[3] = x;
-}
-
-static void
-put24(uchar *p, int x)
-{
- p[0] = x>>16;
- p[1] = x>>8;
- p[2] = x;
-}
-
-static void
-put16(uchar *p, int x)
-{
- p[0] = x>>8;
- p[1] = x;
-}
-
-static int
-get24(uchar *p)
-{
- return (p[0]<<16)|(p[1]<<8)|p[2];
-}
-
-static int
-get16(uchar *p)
-{
- return (p[0]<<8)|p[1];
-}
-
-static Bytes*
-newbytes(int len)
-{
- Bytes* ans;
-
- if(len < 0)
- abort();
- ans = emalloc(sizeof(Bytes) + len);
- ans->len = len;
- return ans;
-}
-
-/*
- * newbytes(len), with data initialized from buf
- */
-static Bytes*
-makebytes(uchar* buf, int len)
-{
- Bytes* ans;
-
- ans = newbytes(len);
- memmove(ans->data, buf, len);
- return ans;
-}
-
-static void
-freebytes(Bytes* b)
-{
- free(b);
-}
-
-static mpint*
-bytestomp(Bytes* bytes)
-{
- return betomp(bytes->data, bytes->len, nil);
-}
-
-/*
- * Convert mpint* to Bytes, putting high order byte first.
- */
-static Bytes*
-mptobytes(mpint *big, int len)
-{
- Bytes* ans;
-
- if(len == 0) len++;
- ans = newbytes(len);
- mptober(big, ans->data, ans->len);
- return ans;
-}
-
-/* len is number of ints */
-static Ints*
-newints(int len)
-{
- Ints* ans;
-
- if(len < 0 || len > ((uint)-1>>1)/sizeof(int))
- abort();
- ans = emalloc(sizeof(Ints) + len*sizeof(int));
- ans->len = len;
- return ans;
-}
-
-static void
-freeints(Ints* b)
-{
- free(b);
-}
-
-static int
-lookupid(Ints* b, int id)
-{
- int i;
-
- for(i=0; i<b->len; i++)
- if(b->data[i] == id)
- return i;
- return -1;
-}
--- a/libsec/tsmemcmp.c
+++ /dev/null
@@ -1,25 +1,0 @@
-#include "os.h"
-#include <libsec.h>
-
-/*
- * timing safe memcmp()
- */
-int
-tsmemcmp(void *a1, void *a2, ulong n)
-{
- int lt, gt, c1, c2, r, m;
- uchar *s1, *s2;
-
- r = m = 0;
- s1 = a1;
- s2 = a2;
- while(n--){
- c1 = *s1++;
- c2 = *s2++;
- lt = (c1 - c2) >> 8;
- gt = (c2 - c1) >> 8;
- r |= (lt - gt) & ~m;
- m |= lt | gt;
- }
- return r;
-}
--- a/libsec/x509.c
+++ /dev/null
@@ -1,3020 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <mp.h>
-#include <libsec.h>
-
-/*=============================================================*/
-/* general ASN1 declarations and parsing
- *
- * For now, this is used only for extracting the key from an
- * X509 certificate, so the entire collection is hidden. But
- * someday we should probably make the functions visible and
- * give them their own man page.
- */
-typedef struct Elem Elem;
-typedef struct Tag Tag;
-typedef struct Value Value;
-typedef struct Bytes Bytes;
-typedef struct Ints Ints;
-typedef struct Bits Bits;
-typedef struct Elist Elist;
-
-/* tag classes */
-#define Universal 0
-#define Context 0x80
-
-/* universal tags */
-#define BOOLEAN 1
-#define INTEGER 2
-#define BIT_STRING 3
-#define OCTET_STRING 4
-#define NULLTAG 5
-#define OBJECT_ID 6
-#define ObjectDescriptor 7
-#define EXTERNAL 8
-#define REAL 9
-#define ENUMERATED 10
-#define EMBEDDED_PDV 11
-#define UTF8String 12
-#define SEQUENCE 16 /* also SEQUENCE OF */
-#define SETOF 17 /* also SETOF OF */
-#define NumericString 18
-#define PrintableString 19
-#define TeletexString 20
-#define VideotexString 21
-#define IA5String 22
-#define UTCTime 23
-#define GeneralizedTime 24
-#define GraphicString 25
-#define VisibleString 26
-#define GeneralString 27
-#define UniversalString 28
-#define BMPString 30
-
-struct Bytes {
- int len;
- uchar data[];
-};
-
-struct Ints {
- int len;
- int data[];
-};
-
-struct Bits {
- int len; /* number of bytes */
- int unusedbits; /* unused bits in last byte */
- uchar data[]; /* most-significant bit first */
-};
-
-struct Tag {
- int class;
- int num;
-};
-
-enum { VBool, VInt, VOctets, VBigInt, VReal, VOther,
- VBitString, VNull, VEOC, VObjId, VString, VSeq, VSet };
-struct Value {
- int tag; /* VBool, etc. */
- union {
- int boolval;
- int intval;
- Bytes* octetsval;
- Bytes* bigintval;
- Bytes* realval; /* undecoded; hardly ever used */
- Bytes* otherval;
- Bits* bitstringval;
- Ints* objidval;
- char* stringval;
- Elist* seqval;
- Elist* setval;
- } u; /* (Don't use anonymous unions, for ease of porting) */
-};
-
-struct Elem {
- Tag tag;
- Value val;
-};
-
-struct Elist {
- Elist* tl;
- Elem hd;
-};
-
-/* decoding errors */
-enum { ASN_OK, ASN_ESHORT, ASN_ETOOBIG, ASN_EVALLEN,
- ASN_ECONSTR, ASN_EPRIM, ASN_EINVAL, ASN_EUNIMPL };
-
-
-/* here are the functions to consider making extern someday */
-static Bytes* newbytes(int len);
-static Bytes* makebytes(uchar* buf, int len);
-static void freebytes(Bytes* b);
-static Bytes* catbytes(Bytes* b1, Bytes* b2);
-static Ints* newints(int len);
-static Ints* makeints(int* buf, int len);
-static void freeints(Ints* b);
-static Bits* newbits(int len);
-static Bits* makebits(uchar* buf, int len, int unusedbits);
-static void freebits(Bits* b);
-static Elist* mkel(Elem e, Elist* tail);
-static void freeelist(Elist* el);
-static int elistlen(Elist* el);
-static int is_seq(Elem* pe, Elist** pseq);
-static int is_set(Elem* pe, Elist** pset);
-static int is_int(Elem* pe, int* pint);
-static int is_bigint(Elem* pe, Bytes** pbigint);
-static int is_bitstring(Elem* pe, Bits** pbits);
-static int is_octetstring(Elem* pe, Bytes** poctets);
-static int is_oid(Elem* pe, Ints** poid);
-static int is_string(Elem* pe, char** pstring);
-static int is_time(Elem* pe, char** ptime);
-static int decode(uchar* a, int alen, Elem* pelem);
-static int encode(Elem e, Bytes** pbytes);
-static int oid_lookup(Ints* o, Ints** tab);
-static void freevalfields(Value* v);
-static mpint *asn1mpint(Elem *e);
-static void edump(Elem);
-
-#define TAG_MASK 0x1F
-#define CONSTR_MASK 0x20
-#define CLASS_MASK 0xC0
-#define MAXOBJIDLEN 20
-
-static int ber_decode(uchar** pp, uchar* pend, Elem* pelem);
-static int tag_decode(uchar** pp, uchar* pend, Tag* ptag, int* pisconstr);
-static int length_decode(uchar** pp, uchar* pend, int* plength);
-static int value_decode(uchar** pp, uchar* pend, int length, int kind, int isconstr, Value* pval);
-static int int_decode(uchar** pp, uchar* pend, int count, int unsgned, int* pint);
-static int uint7_decode(uchar** pp, uchar* pend, int* pint);
-static int octet_decode(uchar** pp, uchar* pend, int length, int isconstr, Bytes** pbytes);
-static int seq_decode(uchar** pp, uchar* pend, int length, int isconstr, Elist** pelist);
-static int enc(uchar** pp, Elem e, int lenonly);
-static int val_enc(uchar** pp, Elem e, int *pconstr, int lenonly);
-static void uint7_enc(uchar** pp, int num, int lenonly);
-static void int_enc(uchar** pp, int num, int unsgned, int lenonly);
-
-static void *
-emalloc(int n)
-{
- void *p;
- if(n==0)
- n=1;
- p = malloc(n);
- if(p == nil)
- sysfatal("out of memory");
- memset(p, 0, n);
- setmalloctag(p, getcallerpc(&n));
- return p;
-}
-
-/*
- * Decode a[0..len] as a BER encoding of an ASN1 type.
- * The return value is one of ASN_OK, etc.
- * Depending on the error, the returned elem may or may not
- * be nil.
- */
-static int
-decode(uchar* a, int alen, Elem* pelem)
-{
- uchar* p = a;
- int err;
-
- err = ber_decode(&p, &a[alen], pelem);
- if(err == ASN_OK && p != &a[alen])
- err = ASN_EVALLEN;
- return err;
-}
-
-/*
- * All of the following decoding routines take arguments:
- * uchar **pp;
- * uchar *pend;
- * Where parsing is supposed to start at **pp, and when parsing
- * is done, *pp is updated to point at next char to be parsed.
- * The pend pointer is just past end of string; an error should
- * be returned parsing hasn't finished by then.
- *
- * The returned int is ASN_OK if all went fine, else ASN_ESHORT, etc.
- * The remaining argument(s) are pointers to where parsed entity goes.
- */
-
-/* Decode an ASN1 'Elem' (tag, length, value) */
-static int
-ber_decode(uchar** pp, uchar* pend, Elem* pelem)
-{
- int err;
- int isconstr;
- int length;
- Tag tag;
- Value val;
-
- memset(pelem, 0, sizeof(*pelem));
- err = tag_decode(pp, pend, &tag, &isconstr);
- if(err == ASN_OK) {
- err = length_decode(pp, pend, &length);
- if(err == ASN_OK) {
- if(tag.class == Universal)
- err = value_decode(pp, pend, length, tag.num, isconstr, &val);
- else
- err = value_decode(pp, pend, length, OCTET_STRING, 0, &val);
- if(err == ASN_OK) {
- pelem->tag = tag;
- pelem->val = val;
- }
- }
- }
- return err;
-}
-
-/* Decode a tag field */
-static int
-tag_decode(uchar** pp, uchar* pend, Tag* ptag, int* pisconstr)
-{
- int err;
- int v;
- uchar* p;
-
- err = ASN_OK;
- p = *pp;
- if(pend-p >= 2) {
- v = *p++;
- ptag->class = v&CLASS_MASK;
- if(v&CONSTR_MASK)
- *pisconstr = 1;
- else
- *pisconstr = 0;
- v &= TAG_MASK;
- if(v == TAG_MASK)
- err = uint7_decode(&p, pend, &v);
- ptag->num = v;
- }
- else
- err = ASN_ESHORT;
- *pp = p;
- return err;
-}
-
-/* Decode a length field */
-static int
-length_decode(uchar** pp, uchar* pend, int* plength)
-{
- int err;
- int num;
- int v;
- uchar* p;
-
- err = ASN_OK;
- num = 0;
- p = *pp;
- if(p < pend) {
- v = *p++;
- if(v&0x80)
- err = int_decode(&p, pend, v&0x7F, 1, &num);
- else
- num = v;
- }
- else
- err = ASN_ESHORT;
- *pp = p;
- *plength = num;
- return err;
-}
-
-/* Decode a value field */
-static int
-value_decode(uchar** pp, uchar* pend, int length, int kind, int isconstr, Value* pval)
-{
- int err;
- Bytes* va;
- int num;
- int bitsunused;
- int subids[MAXOBJIDLEN];
- int isubid;
- Elist* vl;
- uchar* p;
- uchar* pe;
-
- err = ASN_OK;
- p = *pp;
- if(length == -1) { /* "indefinite" length spec */
- if(!isconstr)
- err = ASN_EINVAL;
- }
- else if(p + length > pend)
- err = ASN_EVALLEN;
- if(err != ASN_OK)
- return err;
-
- switch(kind) {
- case 0:
- /* marker for end of indefinite constructions */
- if(length == 0)
- pval->tag = VNull;
- else
- err = ASN_EINVAL;
- break;
-
- case BOOLEAN:
- if(isconstr)
- err = ASN_ECONSTR;
- else if(length != 1)
- err = ASN_EVALLEN;
- else {
- pval->tag = VBool;
- pval->u.boolval = (*p++ != 0);
- }
- break;
-
- case INTEGER:
- case ENUMERATED:
- if(isconstr)
- err = ASN_ECONSTR;
- else if(length <= 4) {
- err = int_decode(&p, pend, length, 0, &num);
- if(err == ASN_OK) {
- pval->tag = VInt;
- pval->u.intval = num;
- }
- }
- else {
- pval->tag = VBigInt;
- pval->u.bigintval = makebytes(p, length);
- p += length;
- }
- break;
-
- case BIT_STRING:
- pval->tag = VBitString;
- if(isconstr) {
- if(length == -1 && p + 2 <= pend && *p == 0 && *(p+1) ==0) {
- pval->u.bitstringval = makebits(0, 0, 0);
- p += 2;
- }
- else /* TODO: recurse and concat results */
- err = ASN_EUNIMPL;
- }
- else {
- if(length < 2) {
- if(length == 1 && *p == 0) {
- pval->u.bitstringval = makebits(0, 0, 0);
- p++;
- }
- else
- err = ASN_EINVAL;
- }
- else {
- bitsunused = *p;
- if(bitsunused > 7)
- err = ASN_EINVAL;
- else if(length > 0x0FFFFFFF)
- err = ASN_ETOOBIG;
- else {
- pval->u.bitstringval = makebits(p+1, length-1, bitsunused);
- p += length;
- }
- }
- }
- break;
-
- case OCTET_STRING:
- case ObjectDescriptor:
- err = octet_decode(&p, pend, length, isconstr, &va);
- if(err == ASN_OK) {
- pval->tag = VOctets;
- pval->u.octetsval = va;
- }
- break;
-
- case NULLTAG:
- if(isconstr)
- err = ASN_ECONSTR;
- else if(length != 0)
- err = ASN_EVALLEN;
- else
- pval->tag = VNull;
- break;
-
- case OBJECT_ID:
- if(isconstr)
- err = ASN_ECONSTR;
- else if(length == 0)
- err = ASN_EVALLEN;
- else {
- isubid = 0;
- pe = p+length;
- while(p < pe && isubid < MAXOBJIDLEN) {
- err = uint7_decode(&p, pend, &num);
- if(err != ASN_OK)
- break;
- if(isubid == 0) {
- subids[isubid++] = num / 40;
- subids[isubid++] = num % 40;
- }
- else
- subids[isubid++] = num;
- }
- if(err == ASN_OK) {
- if(p != pe)
- err = ASN_EVALLEN;
- else {
- pval->tag = VObjId;
- pval->u.objidval = makeints(subids, isubid);
- }
- }
- }
- break;
-
- case EXTERNAL:
- case EMBEDDED_PDV:
- /* TODO: parse this internally */
- if(p+length > pend)
- err = ASN_EVALLEN;
- else {
- pval->tag = VOther;
- pval->u.otherval = makebytes(p, length);
- p += length;
- }
- break;
-
- case REAL:
- /* Let the application decode */
- if(isconstr)
- err = ASN_ECONSTR;
- else if(p+length > pend)
- err = ASN_EVALLEN;
- else {
- pval->tag = VReal;
- pval->u.realval = makebytes(p, length);
- p += length;
- }
- break;
-
- case SEQUENCE:
- err = seq_decode(&p, pend, length, isconstr, &vl);
- if(err == ASN_OK) {
- pval->tag = VSeq ;
- pval->u.seqval = vl;
- }
- break;
-
- case SETOF:
- err = seq_decode(&p, pend, length, isconstr, &vl);
- if(err == ASN_OK) {
- pval->tag = VSet;
- pval->u.setval = vl;
- }
- break;
-
- case UTF8String:
- case NumericString:
- case PrintableString:
- case TeletexString:
- case VideotexString:
- case IA5String:
- case UTCTime:
- case GeneralizedTime:
- case GraphicString:
- case VisibleString:
- case GeneralString:
- case UniversalString:
- case BMPString:
- err = octet_decode(&p, pend, length, isconstr, &va);
- if(err == ASN_OK) {
- uchar *s;
- char *d;
- Rune r;
- int n;
-
- switch(kind){
- case UniversalString:
- n = va->len / 4;
- d = emalloc(n*UTFmax+1);
- pval->u.stringval = d;
- s = va->data;
- while(n > 0){
- r = s[0]<<24 | s[1]<<16 | s[2]<<8 | s[3];
- if(r == 0)
- break;
- n--;
- s += 4;
- d += runetochar(d, &r);
- }
- *d = 0;
- break;
- case BMPString:
- n = va->len / 2;
- d = emalloc(n*UTFmax+1);
- pval->u.stringval = d;
- s = va->data;
- while(n > 0){
- r = s[0]<<8 | s[1];
- if(r == 0)
- break;
- n--;
- s += 2;
- d += runetochar(d, &r);
- }
- *d = 0;
- break;
- default:
- n = va->len;
- d = emalloc(n+1);
- pval->u.stringval = d;
- s = va->data;
- while(n > 0){
- if((*d = *s) == 0)
- break;
- n--;
- s++;
- d++;
- }
- *d = 0;
- break;
- }
- if(n != 0){
- err = ASN_EINVAL;
- free(pval->u.stringval);
- } else
- pval->tag = VString;
- free(va);
- }
- break;
-
- default:
- if(p+length > pend)
- err = ASN_EVALLEN;
- else {
- pval->tag = VOther;
- pval->u.otherval = makebytes(p, length);
- p += length;
- }
- break;
- }
- *pp = p;
- return err;
-}
-
-/*
- * Decode an int in format where count bytes are
- * concatenated to form value.
- * Although ASN1 allows any size integer, we return
- * an error if the result doesn't fit in a 32-bit int.
- * If unsgned is not set, make sure to propagate sign bit.
- */
-static int
-int_decode(uchar** pp, uchar* pend, int count, int unsgned, int* pint)
-{
- int err;
- int num;
- uchar* p;
-
- p = *pp;
- err = ASN_OK;
- num = 0;
- if(p+count <= pend) {
- if((count > 4) || (unsgned && count == 4 && (*p&0x80)))
- err = ASN_ETOOBIG;
- else {
- if(!unsgned && count > 0 && count < 4 && (*p&0x80))
- num = -1; /* set all bits, initially */
- while(count--)
- num = (num << 8)|(*p++);
- }
- }
- else
- err = ASN_ESHORT;
- *pint = num;
- *pp = p;
- return err;
-}
-
-/*
- * Decode an unsigned int in format where each
- * byte except last has high bit set, and remaining
- * seven bits of each byte are concatenated to form value.
- * Although ASN1 allows any size integer, we return
- * an error if the result doesn't fit in a 32 bit int.
- */
-static int
-uint7_decode(uchar** pp, uchar* pend, int* pint)
-{
- int err;
- int num;
- int more;
- int v;
- uchar* p;
-
- p = *pp;
- err = ASN_OK;
- num = 0;
- more = 1;
- while(more && p < pend) {
- v = *p++;
- if(num&0x7F000000) {
- err = ASN_ETOOBIG;
- break;
- }
- num <<= 7;
- more = v&0x80;
- num |= (v&0x7F);
- }
- if(p == pend)
- err = ASN_ESHORT;
- *pint = num;
- *pp = p;
- return err;
-}
-
-/*
- * Decode an octet string, recursively if isconstr.
- * We've already checked that length==-1 implies isconstr==1,
- * and otherwise that specified length fits within (*pp..pend)
- */
-static int
-octet_decode(uchar** pp, uchar* pend, int length, int isconstr, Bytes** pbytes)
-{
- int err;
- uchar* p;
- Bytes* ans;
- Bytes* newans;
- uchar* pstart;
- uchar* pold;
- Elem elem;
-
- err = ASN_OK;
- p = *pp;
- ans = nil;
- if(length >= 0 && !isconstr) {
- ans = makebytes(p, length);
- p += length;
- }
- else {
- /* constructed, either definite or indefinite length */
- pstart = p;
- for(;;) {
- if(length >= 0 && p >= pstart + length) {
- if(p != pstart + length)
- err = ASN_EVALLEN;
- break;
- }
- pold = p;
- err = ber_decode(&p, pend, &elem);
- if(err != ASN_OK)
- break;
- switch(elem.val.tag) {
- case VOctets:
- newans = catbytes(ans, elem.val.u.octetsval);
- freevalfields(&elem.val);
- freebytes(ans);
- ans = newans;
- break;
-
- case VEOC:
- if(length == -1)
- goto cloop_done;
- /* no break */
- default:
- freevalfields(&elem.val);
- p = pold;
- err = ASN_EINVAL;
- goto cloop_done;
- }
- }
-cloop_done:
- if(err != ASN_OK){
- freebytes(ans);
- ans = nil;
- }
- }
- *pp = p;
- *pbytes = ans;
- return err;
-}
-
-/*
- * Decode a sequence or set.
- * We've already checked that length==-1 implies isconstr==1,
- * and otherwise that specified length fits within (*p..pend)
- */
-static int
-seq_decode(uchar** pp, uchar* pend, int length, int isconstr, Elist** pelist)
-{
- int err;
- uchar* p;
- uchar* pstart;
- uchar* pold;
- Elist* ans;
- Elem elem;
- Elist* lve;
- Elist* lveold;
-
- err = ASN_OK;
- ans = nil;
- p = *pp;
- if(!isconstr)
- err = ASN_EPRIM;
- else {
- /* constructed, either definite or indefinite length */
- lve = nil;
- pstart = p;
- for(;;) {
- if(length >= 0 && p >= pstart + length) {
- if(p != pstart + length)
- err = ASN_EVALLEN;
- break;
- }
- pold = p;
- err = ber_decode(&p, pend, &elem);
- if(err != ASN_OK)
- break;
- if(elem.val.tag == VEOC) {
- if(length != -1) {
- p = pold;
- err = ASN_EINVAL;
- }
- break;
- }
- else
- lve = mkel(elem, lve);
- }
- if(err != ASN_OK)
- freeelist(lve);
- else {
- /* reverse back to original order */
- while(lve != nil) {
- lveold = lve;
- lve = lve->tl;
- lveold->tl = ans;
- ans = lveold;
- }
- }
- }
- *pp = p;
- *pelist = ans;
- return err;
-}
-
-/*
- * Encode e by BER rules, putting answer in *pbytes.
- * This is done by first calling enc with lenonly==1
- * to get the length of the needed buffer,
- * then allocating the buffer and using enc again to fill it up.
- */
-static int
-encode(Elem e, Bytes** pbytes)
-{
- uchar* p;
- Bytes* ans;
- int err;
- uchar uc;
-
- p = &uc;
- err = enc(&p, e, 1);
- if(err == ASN_OK) {
- ans = newbytes(p-&uc);
- p = ans->data;
- err = enc(&p, e, 0);
- *pbytes = ans;
- }
- return err;
-}
-
-/*
- * The various enc functions take a pointer to a pointer
- * into a buffer, and encode their entity starting there,
- * updating the pointer afterwards.
- * If lenonly is 1, only the pointer update is done,
- * allowing enc to be called first to calculate the needed
- * buffer length.
- * If lenonly is 0, it is assumed that the answer will fit.
- */
-
-static int
-enc(uchar** pp, Elem e, int lenonly)
-{
- int err;
- int vlen;
- int constr;
- Tag tag;
- int v;
- int ilen;
- uchar* p;
- uchar* psave;
-
- p = *pp;
- err = val_enc(&p, e, &constr, 1);
- if(err != ASN_OK)
- return err;
- vlen = p - *pp;
- p = *pp;
- tag = e.tag;
- v = tag.class|constr;
- if(tag.num < 31) {
- if(!lenonly)
- *p = (v|tag.num);
- p++;
- }
- else {
- if(!lenonly)
- *p = (v|31);
- p++;
- if(tag.num < 0)
- return ASN_EINVAL;
- uint7_enc(&p, tag.num, lenonly);
- }
- if(vlen < 0x80) {
- if(!lenonly)
- *p = vlen;
- p++;
- }
- else {
- psave = p;
- int_enc(&p, vlen, 1, 1);
- ilen = p-psave;
- p = psave;
- if(!lenonly) {
- *p++ = (0x80 | ilen);
- int_enc(&p, vlen, 1, 0);
- }
- else
- p += 1 + ilen;
- }
- if(!lenonly)
- val_enc(&p, e, &constr, 0);
- else
- p += vlen;
- *pp = p;
- return err;
-}
-
-static int
-val_enc(uchar** pp, Elem e, int *pconstr, int lenonly)
-{
- int err;
- uchar* p;
- int kind;
- int cl;
- int v;
- Bytes* bb = nil;
- Bits* bits;
- Ints* oid;
- int k;
- Elist* el;
- char* s;
-
- p = *pp;
- err = ASN_OK;
- kind = e.tag.num;
- cl = e.tag.class;
- *pconstr = 0;
- if(cl != Universal) {
- switch(e.val.tag) {
- case VBool:
- kind = BOOLEAN;
- break;
- case VInt:
- kind = INTEGER;
- break;
- case VBigInt:
- kind = INTEGER;
- break;
- case VOctets:
- kind = OCTET_STRING;
- break;
- case VReal:
- kind = REAL;
- break;
- case VOther:
- kind = OCTET_STRING;
- break;
- case VBitString:
- kind = BIT_STRING;
- break;
- case VNull:
- kind = NULLTAG;
- break;
- case VObjId:
- kind = OBJECT_ID;
- break;
- case VString:
- kind = UniversalString;
- break;
- case VSeq:
- kind = SEQUENCE;
- break;
- case VSet:
- kind = SETOF;
- break;
- }
- }
- switch(kind) {
- case BOOLEAN:
- if(is_int(&e, &v)) {
- if(v != 0)
- v = 255;
- int_enc(&p, v, 1, lenonly);
- }
- else
- err = ASN_EINVAL;
- break;
-
- case INTEGER:
- case ENUMERATED:
- if(is_int(&e, &v))
- int_enc(&p, v, 0, lenonly);
- else {
- if(is_bigint(&e, &bb)) {
- if(!lenonly)
- memmove(p, bb->data, bb->len);
- p += bb->len;
- }
- else
- err = ASN_EINVAL;
- }
- break;
-
- case BIT_STRING:
- if(is_bitstring(&e, &bits)) {
- if(bits->len == 0) {
- if(!lenonly)
- *p = 0;
- p++;
- }
- else {
- v = bits->unusedbits;
- if(v < 0 || v > 7)
- err = ASN_EINVAL;
- else {
- if(!lenonly) {
- *p = v;
- memmove(p+1, bits->data, bits->len);
- }
- p += 1 + bits->len;
- }
- }
- }
- else
- err = ASN_EINVAL;
- break;
-
- case OCTET_STRING:
- case ObjectDescriptor:
- case EXTERNAL:
- case REAL:
- case EMBEDDED_PDV:
- bb = nil;
- switch(e.val.tag) {
- case VOctets:
- bb = e.val.u.octetsval;
- break;
- case VReal:
- bb = e.val.u.realval;
- break;
- case VOther:
- bb = e.val.u.otherval;
- break;
- }
- if(bb != nil) {
- if(!lenonly)
- memmove(p, bb->data, bb->len);
- p += bb->len;
- }
- else
- err = ASN_EINVAL;
- break;
-
- case NULLTAG:
- break;
-
- case OBJECT_ID:
- if(is_oid(&e, &oid)) {
- for(k = 0; k < oid->len; k++) {
- v = oid->data[k];
- if(k == 0) {
- v *= 40;
- if(oid->len > 1)
- v += oid->data[++k];
- }
- uint7_enc(&p, v, lenonly);
- }
- }
- else
- err = ASN_EINVAL;
- break;
-
- case SEQUENCE:
- case SETOF:
- el = nil;
- if(e.val.tag == VSeq)
- el = e.val.u.seqval;
- else if(e.val.tag == VSet)
- el = e.val.u.setval;
- else
- err = ASN_EINVAL;
- if(el != nil) {
- *pconstr = CONSTR_MASK;
- for(; el != nil; el = el->tl) {
- err = enc(&p, el->hd, lenonly);
- if(err != ASN_OK)
- break;
- }
- }
- break;
-
- case UTF8String:
- case NumericString:
- case PrintableString:
- case TeletexString:
- case VideotexString:
- case IA5String:
- case UTCTime:
- case GeneralizedTime:
- case GraphicString:
- case VisibleString:
- case GeneralString:
- case UniversalString:
- case BMPString:
- if(e.val.tag == VString) {
- s = e.val.u.stringval;
- if(s != nil) {
- v = strlen(s);
- if(!lenonly)
- memmove(p, s, v);
- p += v;
- }
- }
- else
- err = ASN_EINVAL;
- break;
-
- default:
- err = ASN_EINVAL;
- }
- *pp = p;
- return err;
-}
-
-/*
- * Encode num as unsigned 7 bit values with top bit 1 on all bytes
- * except last, only putting in bytes if !lenonly.
- */
-static void
-uint7_enc(uchar** pp, int num, int lenonly)
-{
- int n;
- int v;
- int k;
- uchar* p;
-
- p = *pp;
- n = 1;
- v = num >> 7;
- while(v > 0) {
- v >>= 7;
- n++;
- }
- if(lenonly)
- p += n;
- else {
- for(k = (n - 1)*7; k > 0; k -= 7)
- *p++= ((num >> k)|0x80);
- *p++ = (num&0x7F);
- }
- *pp = p;
-}
-
-/*
- * Encode num as unsigned or signed integer,
- * only putting in bytes if !lenonly.
- * Encoding is length followed by bytes to concatenate.
- */
-static void
-int_enc(uchar** pp, int num, int unsgned, int lenonly)
-{
- int v;
- int n;
- int prevv;
- int k;
- uchar* p;
-
- p = *pp;
- v = num;
- if(v < 0)
- v = -(v + 1);
- n = 1;
- prevv = v;
- v >>= 8;
- while(v > 0) {
- prevv = v;
- v >>= 8;
- n++;
- }
- if(!unsgned && (prevv&0x80))
- n++;
- if(lenonly)
- p += n;
- else {
- for(k = (n - 1)*8; k >= 0; k -= 8)
- *p++ = (num >> k);
- }
- *pp = p;
-}
-
-static int
-ints_eq(Ints* a, Ints* b)
-{
- int alen;
- int i;
-
- alen = a->len;
- if(alen != b->len)
- return 0;
- for(i = 0; i < alen; i++)
- if(a->data[i] != b->data[i])
- return 0;
- return 1;
-}
-
-/*
- * Look up o in tab (which must have nil entry to terminate).
- * Return index of matching entry, or -1 if none.
- */
-static int
-oid_lookup(Ints* o, Ints** tab)
-{
- int i;
-
- for(i = 0; tab[i] != nil; i++)
- if(ints_eq(o, tab[i]))
- return i;
- return -1;
-}
-
-/*
- * Return true if *pe is a SEQUENCE, and set *pseq to
- * the value of the sequence if so.
- */
-static int
-is_seq(Elem* pe, Elist** pseq)
-{
- if(pe->tag.class == Universal && pe->tag.num == SEQUENCE && pe->val.tag == VSeq) {
- *pseq = pe->val.u.seqval;
- return 1;
- }
- return 0;
-}
-
-static int
-is_set(Elem* pe, Elist** pset)
-{
- if(pe->tag.class == Universal && pe->tag.num == SETOF && pe->val.tag == VSet) {
- *pset = pe->val.u.setval;
- return 1;
- }
- return 0;
-}
-
-static int
-is_int(Elem* pe, int* pint)
-{
- if(pe->tag.class == Universal) {
- if(pe->tag.num == INTEGER && pe->val.tag == VInt) {
- *pint = pe->val.u.intval;
- return 1;
- }
- else if(pe->tag.num == BOOLEAN && pe->val.tag == VBool) {
- *pint = pe->val.u.boolval;
- return 1;
- }
- }
- return 0;
-}
-
-/*
- * for convience, all VInt's are readable via this routine,
- * as well as all VBigInt's
- */
-static int
-is_bigint(Elem* pe, Bytes** pbigint)
-{
- if(pe->tag.class == Universal && pe->tag.num == INTEGER && pe->val.tag == VBigInt) {
- *pbigint = pe->val.u.bigintval;
- return 1;
- }
- return 0;
-}
-
-static int
-is_bitstring(Elem* pe, Bits** pbits)
-{
- if(pe->tag.class == Universal && pe->tag.num == BIT_STRING && pe->val.tag == VBitString) {
- *pbits = pe->val.u.bitstringval;
- return 1;
- }
- return 0;
-}
-
-static int
-is_octetstring(Elem* pe, Bytes** poctets)
-{
- if(pe->tag.class == Universal && pe->tag.num == OCTET_STRING && pe->val.tag == VOctets) {
- *poctets = pe->val.u.octetsval;
- return 1;
- }
- return 0;
-}
-
-static int
-is_oid(Elem* pe, Ints** poid)
-{
- if(pe->tag.class == Universal && pe->tag.num == OBJECT_ID && pe->val.tag == VObjId) {
- *poid = pe->val.u.objidval;
- return 1;
- }
- return 0;
-}
-
-static int
-is_string(Elem* pe, char** pstring)
-{
- if(pe->tag.class == Universal) {
- switch(pe->tag.num) {
- case UTF8String:
- case NumericString:
- case PrintableString:
- case TeletexString:
- case VideotexString:
- case IA5String:
- case GraphicString:
- case VisibleString:
- case GeneralString:
- case UniversalString:
- case BMPString:
- if(pe->val.tag == VString) {
- *pstring = pe->val.u.stringval;
- return 1;
- }
- }
- }
- return 0;
-}
-
-static int
-is_time(Elem* pe, char** ptime)
-{
- if(pe->tag.class == Universal
- && (pe->tag.num == UTCTime || pe->tag.num == GeneralizedTime)
- && pe->val.tag == VString) {
- *ptime = pe->val.u.stringval;
- return 1;
- }
- return 0;
-}
-
-
-/*
- * malloc and return a new Bytes structure capable of
- * holding len bytes. (len >= 0)
- */
-static Bytes*
-newbytes(int len)
-{
- Bytes* ans;
-
- if(len < 0)
- abort();
- ans = emalloc(sizeof(Bytes) + len);
- ans->len = len;
- return ans;
-}
-
-/*
- * newbytes(len), with data initialized from buf
- */
-static Bytes*
-makebytes(uchar* buf, int len)
-{
- Bytes* ans;
-
- ans = newbytes(len);
- memmove(ans->data, buf, len);
- return ans;
-}
-
-static void
-freebytes(Bytes* b)
-{
- free(b);
-}
-
-/*
- * Make a new Bytes, containing bytes of b1 followed by those of b2.
- * Either b1 or b2 or both can be nil.
- */
-static Bytes*
-catbytes(Bytes* b1, Bytes* b2)
-{
- Bytes* ans;
- int n;
-
- if(b1 == nil) {
- if(b2 == nil)
- ans = newbytes(0);
- else
- ans = makebytes(b2->data, b2->len);
- }
- else if(b2 == nil) {
- ans = makebytes(b1->data, b1->len);
- }
- else {
- n = b1->len + b2->len;
- ans = newbytes(n);
- ans->len = n;
- memmove(ans->data, b1->data, b1->len);
- memmove(ans->data+b1->len, b2->data, b2->len);
- }
- return ans;
-}
-
-/* len is number of ints */
-static Ints*
-newints(int len)
-{
- Ints* ans;
-
- if(len < 0 || len > ((uint)-1>>1)/sizeof(int))
- abort();
- ans = emalloc(sizeof(Ints) + len*sizeof(int));
- ans->len = len;
- return ans;
-}
-
-static Ints*
-makeints(int* buf, int len)
-{
- Ints* ans;
-
- ans = newints(len);
- memmove(ans->data, buf, len*sizeof(int));
- return ans;
-}
-
-static void
-freeints(Ints* b)
-{
- free(b);
-}
-
-/* len is number of bytes */
-static Bits*
-newbits(int len)
-{
- Bits* ans;
-
- if(len < 0)
- abort();
- ans = emalloc(sizeof(Bits) + len);
- ans->len = len;
- ans->unusedbits = 0;
- return ans;
-}
-
-static Bits*
-makebits(uchar* buf, int len, int unusedbits)
-{
- Bits* ans;
-
- ans = newbits(len);
- memmove(ans->data, buf, len);
- ans->unusedbits = unusedbits;
- return ans;
-}
-
-static void
-freebits(Bits* b)
-{
- free(b);
-}
-
-static Elist*
-mkel(Elem e, Elist* tail)
-{
- Elist* el;
-
- el = (Elist*)emalloc(sizeof(Elist));
- setmalloctag(el, getcallerpc(&e));
- el->hd = e;
- el->tl = tail;
- return el;
-}
-
-static int
-elistlen(Elist* el)
-{
- int ans = 0;
- while(el != nil) {
- ans++;
- el = el->tl;
- }
- return ans;
-}
-
-/* Frees elist, but not fields inside values of constituent elems */
-static void
-freeelist(Elist* el)
-{
- Elist* next;
-
- while(el != nil) {
- next = el->tl;
- free(el);
- el = next;
- }
-}
-
-/* free any allocated structures inside v (recursively freeing Elists) */
-static void
-freevalfields(Value* v)
-{
- Elist* el;
- Elist* l;
- if(v == nil)
- return;
- switch(v->tag) {
- case VOctets:
- freebytes(v->u.octetsval);
- break;
- case VBigInt:
- freebytes(v->u.bigintval);
- break;
- case VReal:
- freebytes(v->u.realval);
- break;
- case VOther:
- freebytes(v->u.otherval);
- break;
- case VBitString:
- freebits(v->u.bitstringval);
- break;
- case VObjId:
- freeints(v->u.objidval);
- break;
- case VString:
- free(v->u.stringval);
- break;
- case VSeq:
- el = v->u.seqval;
- for(l = el; l != nil; l = l->tl)
- freevalfields(&l->hd.val);
- freeelist(el);
- break;
- case VSet:
- el = v->u.setval;
- for(l = el; l != nil; l = l->tl)
- freevalfields(&l->hd.val);
- freeelist(el);
- break;
- }
- memset(v, 0, sizeof(*v));
-}
-
-static mpint*
-asn1mpint(Elem *e)
-{
- Bytes *b;
- int v;
-
- if(is_int(e, &v))
- return itomp(v, nil);
- if(is_bigint(e, &b))
- return betomp(b->data, b->len, nil);
- return nil;
-}
-
-/* end of general ASN1 functions */
-
-
-
-
-
-/*=============================================================*/
-/*
- * Decode and parse an X.509 Certificate, defined by this ASN1:
- * Certificate ::= SEQUENCE {
- * certificateInfo CertificateInfo,
- * signatureAlgorithm AlgorithmIdentifier,
- * signature BIT STRING }
- *
- * CertificateInfo ::= SEQUENCE {
- * version [0] INTEGER DEFAULT v1 (0),
- * serialNumber INTEGER,
- * signature AlgorithmIdentifier,
- * issuer Name,
- * validity Validity,
- * subject Name,
- * subjectPublicKeyInfo SubjectPublicKeyInfo }
- * (version v2 has two more fields, optional unique identifiers for
- * issuer and subject; since we ignore these anyway, we won't parse them)
- *
- * Validity ::= SEQUENCE {
- * notBefore UTCTime,
- * notAfter UTCTime }
- *
- * SubjectPublicKeyInfo ::= SEQUENCE {
- * algorithm AlgorithmIdentifier,
- * subjectPublicKey BIT STRING }
- *
- * AlgorithmIdentifier ::= SEQUENCE {
- * algorithm OBJECT IDENTIFER,
- * parameters ANY DEFINED BY ALGORITHM OPTIONAL }
- *
- * Name ::= SEQUENCE OF RelativeDistinguishedName
- *
- * RelativeDistinguishedName ::= SETOF SIZE(1..MAX) OF AttributeTypeAndValue
- *
- * AttributeTypeAndValue ::= SEQUENCE {
- * type OBJECT IDENTIFER,
- * value DirectoryString }
- * (selected attributes have these Object Ids:
- * commonName {2 5 4 3}
- * countryName {2 5 4 6}
- * localityName {2 5 4 7}
- * stateOrProvinceName {2 5 4 8}
- * organizationName {2 5 4 10}
- * organizationalUnitName {2 5 4 11}
- * )
- *
- * DirectoryString ::= CHOICE {
- * teletexString TeletexString,
- * printableString PrintableString,
- * universalString UniversalString }
- *
- * See rfc1423, rfc2437 for AlgorithmIdentifier, subjectPublicKeyInfo, signature.
- *
- * Not yet implemented:
- * CertificateRevocationList ::= SIGNED SEQUENCE{
- * signature AlgorithmIdentifier,
- * issuer Name,
- * lastUpdate UTCTime,
- * nextUpdate UTCTime,
- * revokedCertificates
- * SEQUENCE OF CRLEntry OPTIONAL}
- * CRLEntry ::= SEQUENCE{
- * userCertificate SerialNumber,
- * revocationDate UTCTime}
- */
-
-typedef struct CertX509 {
- int serial;
- char* issuer;
- char* validity_start;
- char* validity_end;
- char* subject;
- int publickey_alg;
- Bits* publickey;
- int signature_alg;
- Bits* signature;
- int curve;
-} CertX509;
-
-/* Algorithm object-ids */
-enum {
- ALG_rsaEncryption,
- ALG_md2WithRSAEncryption,
- ALG_md4WithRSAEncryption,
- ALG_md5WithRSAEncryption,
-
- ALG_sha1WithRSAEncryption,
- ALG_sha1WithRSAEncryptionOiw,
-
- ALG_sha256WithRSAEncryption,
- ALG_sha384WithRSAEncryption,
- ALG_sha512WithRSAEncryption,
- ALG_sha224WithRSAEncryption,
-
- ALG_ecPublicKey,
- ALG_sha1WithECDSA,
- ALG_sha256WithECDSA,
- ALG_sha384WithECDSA,
- ALG_sha512WithECDSA,
-
- ALG_md5,
- ALG_sha1,
- ALG_sha256,
- ALG_sha384,
- ALG_sha512,
- ALG_sha224,
-
- NUMALGS
-};
-
-typedef struct Ints15 {
- int len;
- int data[15];
-} Ints15;
-
-typedef struct DigestAlg {
- int alg;
- DigestState* (*fun)(uchar*,ulong,uchar*,DigestState*);
- int len;
-} DigestAlg;
-
-static DigestAlg alg_md5 = { ALG_md5, md5, MD5dlen};
-static DigestAlg alg_sha1 = { ALG_sha1, sha1, SHA1dlen };
-static DigestAlg alg_sha256 = { ALG_sha256, sha2_256, SHA2_256dlen };
-static DigestAlg alg_sha384 = { ALG_sha384, sha2_384, SHA2_384dlen };
-static DigestAlg alg_sha512 = { ALG_sha512, sha2_512, SHA2_512dlen };
-static DigestAlg alg_sha224 = { ALG_sha224, sha2_224, SHA2_224dlen };
-
-/* maximum length of digest output of the digest algs above */
-enum {
- MAXdlen = SHA2_512dlen,
-};
-
-static Ints15 oid_rsaEncryption = {7, 1, 2, 840, 113549, 1, 1, 1 };
-
-static Ints15 oid_md2WithRSAEncryption = {7, 1, 2, 840, 113549, 1, 1, 2 };
-static Ints15 oid_md4WithRSAEncryption = {7, 1, 2, 840, 113549, 1, 1, 3 };
-static Ints15 oid_md5WithRSAEncryption = {7, 1, 2, 840, 113549, 1, 1, 4 };
-static Ints15 oid_sha1WithRSAEncryption ={7, 1, 2, 840, 113549, 1, 1, 5 };
-static Ints15 oid_sha1WithRSAEncryptionOiw ={6, 1, 3, 14, 3, 2, 29 };
-static Ints15 oid_sha256WithRSAEncryption = {7, 1, 2, 840, 113549, 1, 1, 11 };
-static Ints15 oid_sha384WithRSAEncryption = {7, 1, 2, 840, 113549, 1, 1, 12 };
-static Ints15 oid_sha512WithRSAEncryption = {7, 1, 2, 840, 113549, 1, 1, 13 };
-static Ints15 oid_sha224WithRSAEncryption = {7, 1, 2, 840, 113549, 1, 1, 14 };
-
-static Ints15 oid_ecPublicKey = {6, 1, 2, 840, 10045, 2, 1 };
-static Ints15 oid_sha1WithECDSA = {6, 1, 2, 840, 10045, 4, 1 };
-static Ints15 oid_sha256WithECDSA = {7, 1, 2, 840, 10045, 4, 3, 2 };
-static Ints15 oid_sha384WithECDSA = {7, 1, 2, 840, 10045, 4, 3, 3 };
-static Ints15 oid_sha512WithECDSA = {7, 1, 2, 840, 10045, 4, 3, 4 };
-
-static Ints15 oid_md5 = {6, 1, 2, 840, 113549, 2, 5 };
-static Ints15 oid_sha1 = {6, 1, 3, 14, 3, 2, 26 };
-static Ints15 oid_sha256= {9, 2, 16, 840, 1, 101, 3, 4, 2, 1 };
-static Ints15 oid_sha384= {9, 2, 16, 840, 1, 101, 3, 4, 2, 2 };
-static Ints15 oid_sha512= {9, 2, 16, 840, 1, 101, 3, 4, 2, 3 };
-static Ints15 oid_sha224= {9, 2, 16, 840, 1, 101, 3, 4, 2, 4 };
-
-static Ints *alg_oid_tab[NUMALGS+1] = {
- (Ints*)&oid_rsaEncryption,
- (Ints*)&oid_md2WithRSAEncryption,
- (Ints*)&oid_md4WithRSAEncryption,
- (Ints*)&oid_md5WithRSAEncryption,
-
- (Ints*)&oid_sha1WithRSAEncryption,
- (Ints*)&oid_sha1WithRSAEncryptionOiw,
-
- (Ints*)&oid_sha256WithRSAEncryption,
- (Ints*)&oid_sha384WithRSAEncryption,
- (Ints*)&oid_sha512WithRSAEncryption,
- (Ints*)&oid_sha224WithRSAEncryption,
-
- (Ints*)&oid_ecPublicKey,
- (Ints*)&oid_sha1WithECDSA,
- (Ints*)&oid_sha256WithECDSA,
- (Ints*)&oid_sha384WithECDSA,
- (Ints*)&oid_sha512WithECDSA,
-
- (Ints*)&oid_md5,
- (Ints*)&oid_sha1,
- (Ints*)&oid_sha256,
- (Ints*)&oid_sha384,
- (Ints*)&oid_sha512,
- (Ints*)&oid_sha224,
- nil
-};
-
-static DigestAlg *digestalg[NUMALGS+1] = {
- &alg_md5, &alg_md5, &alg_md5, &alg_md5,
- &alg_sha1, &alg_sha1,
- &alg_sha256, &alg_sha384, &alg_sha512, &alg_sha224,
- &alg_sha256, &alg_sha1, &alg_sha256, &alg_sha384, &alg_sha512,
- &alg_md5, &alg_sha1, &alg_sha256, &alg_sha384, &alg_sha512, &alg_sha224,
- nil
-};
-
-static Bytes* encode_digest(DigestAlg *da, uchar *digest);
-
-static Ints15 oid_secp256r1 = {7, 1, 2, 840, 10045, 3, 1, 7};
-static Ints15 oid_secp384r1 = {5, 1, 3, 132, 0, 34};
-
-static Ints *namedcurves_oid_tab[] = {
- (Ints*)&oid_secp256r1,
- (Ints*)&oid_secp384r1,
- nil,
-};
-static void (*namedcurves[])(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h) = {
- secp256r1,
- secp384r1,
- nil,
-};
-
-static void
-freecert(CertX509* c)
-{
- if(c == nil)
- return;
- free(c->issuer);
- free(c->validity_start);
- free(c->validity_end);
- free(c->subject);
- freebits(c->publickey);
- freebits(c->signature);
- free(c);
-}
-
-/*
- * Parse the Name ASN1 type.
- * The sequence of RelativeDistinguishedName's gives a sort of pathname,
- * from most general to most specific. Each element of the path can be
- * one or more (but usually just one) attribute-value pair, such as
- * countryName="US".
- * We'll just form a "postal-style" address string by concatenating the elements
- * from most specific to least specific, separated by commas.
- * Return name-as-string (which must be freed by caller).
- */
-static char*
-parse_name(Elem* e)
-{
- Elist* el;
- Elem* es;
- Elist* esetl;
- Elem* eat;
- Elist* eatl;
- char* s;
- enum { MAXPARTS = 100 };
- char* parts[MAXPARTS];
- int i;
- int plen;
- char* ans = nil;
-
- if(!is_seq(e, &el))
- goto errret;
- i = 0;
- plen = 0;
- while(el != nil) {
- es = &el->hd;
- if(!is_set(es, &esetl))
- goto errret;
- while(esetl != nil) {
- eat = &esetl->hd;
- if(!is_seq(eat, &eatl) || elistlen(eatl) != 2)
- goto errret;
- if(!is_string(&eatl->tl->hd, &s) || i>=MAXPARTS)
- goto errret;
- parts[i++] = s;
- plen += strlen(s) + 2; /* room for ", " after */
- esetl = esetl->tl;
- }
- el = el->tl;
- }
- if(i > 0) {
- ans = (char*)emalloc(plen);
- *ans = '\0';
- while(--i >= 0) {
- s = parts[i];
- strcat(ans, s);
- if(i > 0)
- strcat(ans, ", ");
- }
- }
-
-errret:
- return ans;
-}
-
-/*
- * Parse an AlgorithmIdentifer ASN1 type.
- * Look up the oid in oid_tab and return one of OID_rsaEncryption, etc..,
- * or -1 if not found.
- * For now, ignore parameters, since none of our algorithms need them.
- */
-static int
-parse_alg(Elem* e)
-{
- Elist* el;
- Ints* oid;
-
- if(!is_seq(e, &el) || el == nil || !is_oid(&el->hd, &oid))
- return -1;
- return oid_lookup(oid, alg_oid_tab);
-}
-
-static int
-parse_curve(Elem* e)
-{
- Elist* el;
- Ints* oid;
-
- if(!is_seq(e, &el) || elistlen(el)<2 || !is_oid(&el->tl->hd, &oid))
- return -1;
- return oid_lookup(oid, namedcurves_oid_tab);
-}
-
-static CertX509*
-decode_cert(uchar *buf, int len)
-{
- int ok = 0;
- int n;
- Elem ecert;
- Elem* ecertinfo;
- Elem* esigalg;
- Elem* esig;
- Elem* eserial;
- Elem* eissuer;
- Elem* evalidity;
- Elem* esubj;
- Elem* epubkey;
- Elist* el;
- Elist* elcert = nil;
- Elist* elcertinfo = nil;
- Elist* elvalidity = nil;
- Elist* elpubkey = nil;
- Bits* bits = nil;
- Bytes* b;
- Elem* e;
- CertX509* c = nil;
-
- if(decode(buf, len, &ecert) != ASN_OK)
- goto errret;
-
- c = (CertX509*)emalloc(sizeof(CertX509));
- c->serial = -1;
- c->issuer = nil;
- c->validity_start = nil;
- c->validity_end = nil;
- c->subject = nil;
- c->publickey_alg = -1;
- c->publickey = nil;
- c->signature_alg = -1;
- c->signature = nil;
-
- /* Certificate */
- if(!is_seq(&ecert, &elcert) || elistlen(elcert) !=3)
- goto errret;
- ecertinfo = &elcert->hd;
- el = elcert->tl;
- esigalg = &el->hd;
- c->signature_alg = parse_alg(esigalg);
- el = el->tl;
- esig = &el->hd;
-
- /* Certificate Info */
- if(!is_seq(ecertinfo, &elcertinfo))
- goto errret;
- n = elistlen(elcertinfo);
- if(n < 6)
- goto errret;
- eserial =&elcertinfo->hd;
- el = elcertinfo->tl;
- /* check for optional version, marked by explicit context tag 0 */
- if(eserial->tag.class == Context && eserial->tag.num == 0) {
- eserial = &el->hd;
- if(n < 7)
- goto errret;
- el = el->tl;
- }
-
- if(parse_alg(&el->hd) != c->signature_alg)
- goto errret;
- el = el->tl;
- eissuer = &el->hd;
- el = el->tl;
- evalidity = &el->hd;
- el = el->tl;
- esubj = &el->hd;
- el = el->tl;
- epubkey = &el->hd;
- if(!is_int(eserial, &c->serial)) {
- if(!is_bigint(eserial, &b))
- goto errret;
- c->serial = -1; /* else we have to change cert struct */
- }
- c->issuer = parse_name(eissuer);
- if(c->issuer == nil)
- goto errret;
- /* Validity */
- if(!is_seq(evalidity, &elvalidity))
- goto errret;
- if(elistlen(elvalidity) != 2)
- goto errret;
- e = &elvalidity->hd;
- if(!is_time(e, &c->validity_start))
- goto errret;
- e->val.u.stringval = nil; /* string ownership transfer */
- e = &elvalidity->tl->hd;
- if(!is_time(e, &c->validity_end))
- goto errret;
- e->val.u.stringval = nil; /* string ownership transfer */
-
- /* resume CertificateInfo */
- c->subject = parse_name(esubj);
- if(c->subject == nil)
- goto errret;
-
- /* SubjectPublicKeyInfo */
- if(!is_seq(epubkey, &elpubkey))
- goto errret;
- if(elistlen(elpubkey) != 2)
- goto errret;
-
- c->publickey_alg = parse_alg(&elpubkey->hd);
- if(c->publickey_alg < 0)
- goto errret;
- c->curve = -1;
- if(c->publickey_alg == ALG_ecPublicKey){
- c->curve = parse_curve(&elpubkey->hd);
- if(c->curve < 0)
- goto errret;
- }
- elpubkey = elpubkey->tl;
- if(!is_bitstring(&elpubkey->hd, &bits))
- goto errret;
- elpubkey->hd.val.u.bitstringval = nil; /* transfer ownership */
- c->publickey = bits;
-
- /*resume Certificate */
- if(c->signature_alg < 0)
- goto errret;
- if(!is_bitstring(esig, &bits))
- goto errret;
- esig->val.u.bitstringval = nil; /* transfer ownership */
- c->signature = bits;
- ok = 1;
-
-errret:
- freevalfields(&ecert.val); /* recurses through lists, too */
- if(!ok){
- freecert(c);
- c = nil;
- }
- return c;
-}
-
-/*
- * RSAPublickKey ::= SEQUENCE {
- * modulus INTEGER,
- * publicExponent INTEGER
- * }
- */
-RSApub*
-asn1toRSApub(uchar *buf, int len)
-{
- Elem e;
- Elist *el;
- RSApub* key;
-
- key = nil;
- if(decode(buf, len, &e) != ASN_OK)
- goto errret;
- if(!is_seq(&e, &el) || elistlen(el) != 2)
- goto errret;
-
- key = rsapuballoc();
- if((key->n = asn1mpint(&el->hd)) == nil)
- goto errret;
- el = el->tl;
- if((key->ek = asn1mpint(&el->hd)) == nil)
- goto errret;
-
- freevalfields(&e.val);
- return key;
-errret:
- freevalfields(&e.val);
- rsapubfree(key);
- return nil;
-
-}
-
-/*
- * RSAPrivateKey ::= SEQUENCE {
- * version Version,
- * modulus INTEGER, -- n
- * publicExponent INTEGER, -- e
- * privateExponent INTEGER, -- d
- * prime1 INTEGER, -- p
- * prime2 INTEGER, -- q
- * exponent1 INTEGER, -- d mod (p-1)
- * exponent2 INTEGER, -- d mod (q-1)
- * coefficient INTEGER -- (inverse of q) mod p }
- */
-RSApriv*
-asn1toRSApriv(uchar *buf, int len)
-{
- int version;
- Elem e;
- Elist *el;
- Bytes *b;
- RSApriv* key = nil;
-
- if(decode(buf, len, &e) != ASN_OK)
- goto errret;
- if(!is_seq(&e, &el))
- goto errret;
-
- if(!is_int(&el->hd, &version) || version != 0)
- goto errret;
-
- if(elistlen(el) != 9){
- if(elistlen(el) == 3
- && parse_alg(&el->tl->hd) == ALG_rsaEncryption
- && is_octetstring(&el->tl->tl->hd, &b)){
- key = asn1toRSApriv(b->data, b->len);
- if(key != nil)
- goto done;
- }
- goto errret;
- }
-
- key = rsaprivalloc();
- el = el->tl;
- if((key->pub.n = asn1mpint(&el->hd)) == nil)
- goto errret;
-
- el = el->tl;
- if((key->pub.ek = asn1mpint(&el->hd)) == nil)
- goto errret;
-
- el = el->tl;
- if((key->dk = asn1mpint(&el->hd)) == nil)
- goto errret;
-
- el = el->tl;
- if((key->q = asn1mpint(&el->hd)) == nil)
- goto errret;
-
- el = el->tl;
- if((key->p = asn1mpint(&el->hd)) == nil)
- goto errret;
-
- el = el->tl;
- if((key->kq = asn1mpint(&el->hd)) == nil)
- goto errret;
-
- el = el->tl;
- if((key->kp = asn1mpint(&el->hd)) == nil)
- goto errret;
-
- el = el->tl;
- if((key->c2 = asn1mpint(&el->hd)) == nil)
- goto errret;
-
-done:
- freevalfields(&e.val);
- return key;
-errret:
- freevalfields(&e.val);
- rsaprivfree(key);
- return nil;
-}
-
-/*
- * digest(CertificateInfo)
- * Our ASN.1 library doesn't return pointers into the original
- * data array, so we need to do a little hand decoding.
- */
-static int
-digest_certinfo(uchar *cert, int ncert, DigestAlg *da, uchar *digest)
-{
- uchar *info, *p, *pend;
- int isconstr, length;
- Tag tag;
- Elem elem;
-
- p = cert;
- pend = cert + ncert;
- if(tag_decode(&p, pend, &tag, &isconstr) != ASN_OK ||
- tag.class != Universal || tag.num != SEQUENCE ||
- length_decode(&p, pend, &length) != ASN_OK ||
- p+length > pend ||
- p+length < p)
- return -1;
- info = p;
- if(ber_decode(&p, pend, &elem) != ASN_OK)
- return -1;
- freevalfields(&elem.val);
- if(elem.tag.num != SEQUENCE)
- return -1;
- (*da->fun)(info, p - info, digest, nil);
- return da->len;
-}
-
-mpint*
-pkcs1padbuf(uchar *buf, int len, mpint *modulus, int blocktype)
-{
- int i, n = (mpsignif(modulus)-1)/8;
- int pad = n - 2 - len;
- uchar *p;
- mpint *mp;
-
- if(pad < 8){
- werrstr("rsa modulus too small");
- return nil;
- }
- if((p = malloc(n)) == nil)
- return nil;
- p[0] = blocktype;
- switch(blocktype){
- default:
- case 1:
- memset(p+1, 0xFF, pad);
- break;
- case 2:
- for(i=1; i <= pad; i++)
- p[i] = 1 + nfastrand(255);
- break;
- }
- p[1+pad] = 0;
- memmove(p+2+pad, buf, len);
- mp = betomp(p, n, nil);
- free(p);
- return mp;
-}
-
-int
-pkcs1unpadbuf(uchar *buf, int len, mpint *modulus, int blocktype)
-{
- uchar *p = buf + 1, *e = buf + len;
-
- if(len < 1 || len != (mpsignif(modulus)-1)/8 || buf[0] != blocktype)
- return -1;
- switch(blocktype){
- default:
- case 1:
- while(p < e && *p == 0xFF)
- p++;
- break;
- case 2:
- while(p < e && *p != 0x00)
- p++;
- break;
- }
- if(p - buf <= 8 || p >= e || *p++ != 0x00)
- return -1;
- memmove(buf, p, len = e - p);
- return len;
-}
-
-static char Ebadsig[] = "bad signature";
-
-char*
-X509rsaverifydigest(uchar *sig, int siglen, uchar *edigest, int edigestlen, RSApub *pk)
-{
- mpint *x, *y;
- DigestAlg **dp;
- Bytes *digest;
- uchar *buf;
- int len;
- char *err;
-
- x = betomp(sig, siglen, nil);
- y = rsaencrypt(pk, x, nil);
- mpfree(x);
- len = mptobe(y, nil, 0, &buf);
- mpfree(y);
-
- err = Ebadsig;
- len = pkcs1unpadbuf(buf, len, pk->n, 1);
- if(len == edigestlen && tsmemcmp(buf, edigest, edigestlen) == 0)
- err = nil;
- for(dp = digestalg; err != nil && *dp != nil; dp++){
- if((*dp)->len != edigestlen)
- continue;
- digest = encode_digest(*dp, edigest);
- if(digest->len == len && tsmemcmp(digest->data, buf, len) == 0)
- err = nil;
- freebytes(digest);
- }
- free(buf);
- return err;
-}
-
-char*
-X509ecdsaverifydigest(uchar *sig, int siglen, uchar *edigest, int edigestlen, ECdomain *dom, ECpub *pub)
-{
- Elem e;
- Elist *el;
- mpint *r, *s;
- char *err;
-
- r = s = nil;
- err = Ebadsig;
- if(decode(sig, siglen, &e) != ASN_OK)
- goto end;
- if(!is_seq(&e, &el) || elistlen(el) != 2)
- goto end;
- r = asn1mpint(&el->hd);
- if(r == nil)
- goto end;
- el = el->tl;
- s = asn1mpint(&el->hd);
- if(s == nil)
- goto end;
- if(ecdsaverify(dom, pub, edigest, edigestlen, r, s))
- err = nil;
-end:
- freevalfields(&e.val);
- mpfree(s);
- mpfree(r);
- return err;
-}
-
-static void
-copysubject(char *name, int nname, char *subject)
-{
- char *e;
-
- if(name == nil)
- return;
- memset(name, 0, nname);
- if(subject == nil)
- return;
- strncpy(name, subject, nname-1);
- e = strchr(name, ',');
- if(e != nil)
- *e = 0; /* take just CN part of Distinguished Name */
-}
-
-ECpub*
-X509toECpub(uchar *cert, int ncert, char *name, int nname, ECdomain *dom)
-{
- CertX509 *c;
- ECpub *pub;
-
- c = decode_cert(cert, ncert);
- if(c == nil)
- return nil;
- copysubject(name, nname, c->subject);
- pub = nil;
- if(c->publickey_alg == ALG_ecPublicKey){
- ecdominit(dom, namedcurves[c->curve]);
- pub = ecdecodepub(dom, c->publickey->data, c->publickey->len);
- if(pub == nil)
- ecdomfree(dom);
- }
- freecert(c);
- return pub;
-}
-
-char*
-X509ecdsaverify(uchar *cert, int ncert, ECdomain *dom, ECpub *pk)
-{
- char *e;
- CertX509 *c;
- int digestlen;
- uchar digest[MAXdlen];
-
- c = decode_cert(cert, ncert);
- if(c == nil)
- return "cannot decode cert";
- digestlen = digest_certinfo(cert, ncert, digestalg[c->signature_alg], digest);
- if(digestlen <= 0){
- freecert(c);
- return "cannot decode certinfo";
- }
- e = X509ecdsaverifydigest(c->signature->data, c->signature->len, digest, digestlen, dom, pk);
- freecert(c);
- return e;
-}
-
-RSApub*
-X509toRSApub(uchar *cert, int ncert, char *name, int nname)
-{
- CertX509 *c;
- RSApub *pub;
-
- c = decode_cert(cert, ncert);
- if(c == nil)
- return nil;
- copysubject(name, nname, c->subject);
- pub = nil;
- if(c->publickey_alg == ALG_rsaEncryption)
- pub = asn1toRSApub(c->publickey->data, c->publickey->len);
- freecert(c);
- return pub;
-}
-
-char*
-X509rsaverify(uchar *cert, int ncert, RSApub *pk)
-{
- char *e;
- CertX509 *c;
- int digestlen;
- uchar digest[MAXdlen];
-
- c = decode_cert(cert, ncert);
- if(c == nil)
- return "cannot decode cert";
- digestlen = digest_certinfo(cert, ncert, digestalg[c->signature_alg], digest);
- if(digestlen <= 0){
- freecert(c);
- return "cannot decode certinfo";
- }
- e = X509rsaverifydigest(c->signature->data, c->signature->len, digest, digestlen, pk);
- freecert(c);
- return e;
-}
-
-/* ------- Elem constructors ---------- */
-static Elem
-Null(void)
-{
- Elem e;
-
- e.tag.class = Universal;
- e.tag.num = NULLTAG;
- e.val.tag = VNull;
- return e;
-}
-
-static Elem
-mkint(int j)
-{
- Elem e;
-
- e.tag.class = Universal;
- e.tag.num = INTEGER;
- e.val.tag = VInt;
- e.val.u.intval = j;
- return e;
-}
-
-static Elem
-mkbigint(mpint *p)
-{
- Elem e;
-
- e.tag.class = Universal;
- e.tag.num = INTEGER;
- e.val.tag = VBigInt;
- e.val.u.bigintval = newbytes((mpsignif(p)+8)/8);
- if(p->sign < 0){
- mpint *s = mpnew(e.val.u.bigintval->len*8+1);
- mpleft(mpone, e.val.u.bigintval->len*8, s);
- mpadd(p, s, s);
- mptober(s, e.val.u.bigintval->data, e.val.u.bigintval->len);
- mpfree(s);
- } else {
- mptober(p, e.val.u.bigintval->data, e.val.u.bigintval->len);
- }
- return e;
-}
-
-static int
-printable(char *s)
-{
- int c;
-
- while((c = (uchar)*s++) != 0){
- if((c >= 'a' && c <= 'z')
- || (c >= 'A' && c <= 'Z')
- || (c >= '0' && c <= '9')
- || strchr("'=()+,-./:? ", c) != nil)
- continue;
- return 0;
- }
- return 1;
-}
-
-#define DirectoryString 0
-
-static Elem
-mkstring(char *s, int t)
-{
- Elem e;
-
- if(t == DirectoryString)
- t = printable(s) ? PrintableString : UTF8String;
- e.tag.class = Universal;
- e.tag.num = t;
- e.val.tag = VString;
- e.val.u.stringval = estrdup(s);
- return e;
-}
-
-static Elem
-mkoctet(uchar *buf, int buflen)
-{
- Elem e;
-
- e.tag.class = Universal;
- e.tag.num = OCTET_STRING;
- e.val.tag = VOctets;
- e.val.u.octetsval = makebytes(buf, buflen);
- return e;
-}
-
-static Elem
-mkbits(uchar *buf, int buflen)
-{
- Elem e;
-
- e.tag.class = Universal;
- e.tag.num = BIT_STRING;
- e.val.tag = VBitString;
- e.val.u.bitstringval = makebits(buf, buflen, 0);
- return e;
-}
-
-static Elem
-mkutc(long t)
-{
- Elem e;
- char utc[50];
- Tm *tm = gmtime(t);
-
- e.tag.class = Universal;
- e.tag.num = UTCTime;
- e.val.tag = VString;
- snprint(utc, sizeof(utc), "%.2d%.2d%.2d%.2d%.2d%.2dZ",
- tm->year % 100, tm->mon+1, tm->mday, tm->hour, tm->min, tm->sec);
- e.val.u.stringval = estrdup(utc);
- return e;
-}
-
-static Elem
-mkoid(Ints *oid)
-{
- Elem e;
-
- e.tag.class = Universal;
- e.tag.num = OBJECT_ID;
- e.val.tag = VObjId;
- e.val.u.objidval = makeints(oid->data, oid->len);
- return e;
-}
-
-static Elem
-mkseq(Elist *el)
-{
- Elem e;
-
- e.tag.class = Universal;
- e.tag.num = SEQUENCE;
- e.val.tag = VSeq;
- e.val.u.seqval = el;
- return e;
-}
-
-static Elem
-mkset(Elist *el)
-{
- Elem e;
-
- e.tag.class = Universal;
- e.tag.num = SETOF;
- e.val.tag = VSet;
- e.val.u.setval = el;
- return e;
-}
-
-static Elem
-mkalg(int alg)
-{
- return mkseq(mkel(mkoid(alg_oid_tab[alg]), mkel(Null(), nil)));
-}
-
-typedef struct Ints7pref {
- int len;
- int data[7];
- char prefix[4];
- int stype;
-} Ints7pref;
-Ints7pref DN_oid[] = {
- {4, 2, 5, 4, 6, 0, 0, 0, "C=", PrintableString},
- {4, 2, 5, 4, 8, 0, 0, 0, "ST=",DirectoryString},
- {4, 2, 5, 4, 7, 0, 0, 0, "L=", DirectoryString},
- {4, 2, 5, 4, 10, 0, 0, 0, "O=", DirectoryString},
- {4, 2, 5, 4, 11, 0, 0, 0, "OU=",DirectoryString},
- {4, 2, 5, 4, 3, 0, 0, 0, "CN=",DirectoryString},
- {7, 1,2,840,113549,1,9,1, "E=", IA5String},
- {7, 0,9,2342,19200300,100,1,25, "DC=",IA5String},
-};
-
-static Elem
-mkname(Ints7pref *oid, char *subj)
-{
- return mkset(mkel(mkseq(mkel(mkoid((Ints*)oid), mkel(mkstring(subj, oid->stype), nil))), nil));
-}
-
-static Elem
-mkDN(char *dn)
-{
- int i, j, nf;
- char *f[20], *prefix, *d2 = estrdup(dn);
- Elist* el = nil;
-
- nf = tokenize(d2, f, nelem(f));
- for(i=nf-1; i>=0; i--){
- for(j=0; j<nelem(DN_oid); j++){
- prefix = DN_oid[j].prefix;
- if(strncmp(f[i],prefix,strlen(prefix))==0){
- el = mkel(mkname(&DN_oid[j],f[i]+strlen(prefix)), el);
- break;
- }
- }
- }
- free(d2);
- return mkseq(el);
-}
-
-/*
- * DigestInfo ::= SEQUENCE {
- * digestAlgorithm AlgorithmIdentifier,
- * digest OCTET STRING }
- */
-static Bytes*
-encode_digest(DigestAlg *da, uchar *digest)
-{
- Bytes *b = nil;
- Elem e = mkseq(
- mkel(mkalg(da->alg),
- mkel(mkoctet(digest, da->len),
- nil)));
- encode(e, &b);
- freevalfields(&e.val);
- return b;
-}
-
-int
-asn1encodedigest(DigestState* (*fun)(uchar*, ulong, uchar*, DigestState*), uchar *digest, uchar *buf, int len)
-{
- Bytes *bytes;
- DigestAlg **dp;
-
- for(dp = digestalg; *dp != nil; dp++){
- if((*dp)->fun != fun)
- continue;
- bytes = encode_digest(*dp, digest);
- if(bytes == nil)
- break;
- if(bytes->len > len){
- freebytes(bytes);
- break;
- }
- len = bytes->len;
- memmove(buf, bytes->data, len);
- freebytes(bytes);
- return len;
- }
- return -1;
-}
-
-static Elem
-mkcont(Elem e, int num)
-{
- e = mkseq(mkel(e, nil));
- e.tag.class = Context;
- e.tag.num = num;
- return e;
-}
-
-static Elem
-mkaltname(char *s)
-{
- Elem e;
- int i;
-
- for(i=0; i<nelem(DN_oid); i++){
- if(strstr(s, DN_oid[i].prefix) != nil)
- return mkcont(mkDN(s), 4); /* DN */
- }
- e = mkstring(s, IA5String);
- e.tag.class = Context;
- e.tag.num = strchr(s, '@') != nil ? 1 : 2; /* email : DNS */
- return e;
-}
-
-static Elist*
-mkaltnames(char *alts)
-{
- Elist *el;
- char *s, *p;
-
- if(alts == nil)
- return nil;
-
- el = nil;
- alts = estrdup(alts);
- for(s = alts; s != nil; s = p){
- while(*s == ' ')
- s++;
- if(*s == '\0')
- break;
- if((p = strchr(s, ',')) != nil)
- *p++ = 0;
- el = mkel(mkaltname(s), el);
- }
- free(alts);
- return el;
-}
-
-static Elist*
-mkextel(Elem e, Ints *oid, Elist *el)
-{
- Bytes *b = nil;
-
- if(encode(e, &b) == ASN_OK){
- el = mkel(mkseq(
- mkel(mkoid(oid),
- mkel(mkoctet(b->data, b->len),
- nil))), el);
- freebytes(b);
- }
- freevalfields(&e.val);
- return el;
-}
-
-static Ints15 oid_subjectAltName = {4, 2, 5, 29, 17 };
-static Ints15 oid_extensionRequest = { 7, 1, 2, 840, 113549, 1, 9, 14};
-
-static Elist*
-mkextensions(char *alts, int req)
-{
- Elist *sl, *xl;
-
- xl = nil;
- if((sl = mkaltnames(alts)) != nil)
- xl = mkextel(mkseq(sl), (Ints*)&oid_subjectAltName, xl);
- if(xl != nil){
- if(req) return mkel(mkcont(mkseq(
- mkel(mkoid((Ints*)&oid_extensionRequest),
- mkel(mkset(mkel(mkseq(xl), nil)), nil))), 0), nil);
- return mkel(mkcont(mkseq(xl), 3), nil);
- }
- return nil;
-}
-
-static char*
-splitalts(char *s)
-{
- int q;
-
- for(q = 0; *s != '\0'; s++){
- if(*s == '\'')
- q ^= 1;
- else if(q == 0 && *s == ','){
- *s++ = 0;
- return s;
- }
- }
- return nil;
-}
-
-static Bytes*
-encode_rsapubkey(RSApub *pk)
-{
- Bytes *b = nil;
- Elem e = mkseq(
- mkel(mkbigint(pk->n),
- mkel(mpsignif(pk->ek)<32 ? mkint(mptoi(pk->ek)) : mkbigint(pk->ek),
- nil)));
- encode(e, &b);
- freevalfields(&e.val);
- return b;
-}
-
-int
-asn1encodeRSApub(RSApub *pk, uchar *buf, int len)
-{
- Bytes *b = encode_rsapubkey(pk);
- if(b == nil)
- return -1;
- if(b->len > len){
- freebytes(b);
- werrstr("buffer too small");
- return -1;
- }
- memmove(buf, b->data, len = b->len);
- freebytes(b);
- return len;
-}
-
-uchar*
-X509rsagen(RSApriv *priv, char *subj, ulong valid[2], int *certlen)
-{
- int serial = 0, sigalg = ALG_sha256WithRSAEncryption;
- uchar *cert = nil;
- Bytes *certbytes, *pkbytes, *certinfobytes, *sigbytes;
- Elem e, certinfo;
- DigestAlg *da;
- uchar digest[MAXdlen], *buf;
- int buflen;
- mpint *pkcs1;
- char *alts;
-
- if((pkbytes = encode_rsapubkey(&priv->pub)) == nil)
- return nil;
-
- subj = estrdup(subj);
- alts = splitalts(subj);
-
- e = mkseq(
- mkel(mkcont(mkint(2), 0),
- mkel(mkint(serial),
- mkel(mkalg(sigalg),
- mkel(mkDN(subj),
- mkel(mkseq(
- mkel(mkutc(valid[0]),
- mkel(mkutc(valid[1]),
- nil))),
- mkel(mkDN(subj),
- mkel(mkseq(
- mkel(mkalg(ALG_rsaEncryption),
- mkel(mkbits(pkbytes->data, pkbytes->len),
- nil))),
- mkextensions(alts, 0)))))))));
- freebytes(pkbytes);
- if(encode(e, &certinfobytes) != ASN_OK)
- goto errret;
-
- da = digestalg[sigalg];
- (*da->fun)(certinfobytes->data, certinfobytes->len, digest, 0);
- freebytes(certinfobytes);
- certinfo = e;
-
- sigbytes = encode_digest(da, digest);
- if(sigbytes == nil)
- goto errret;
- pkcs1 = pkcs1padbuf(sigbytes->data, sigbytes->len, priv->pub.n, 1);
- freebytes(sigbytes);
- if(pkcs1 == nil)
- goto errret;
-
- rsadecrypt(priv, pkcs1, pkcs1);
- buflen = mptobe(pkcs1, nil, 0, &buf);
- mpfree(pkcs1);
- e = mkseq(
- mkel(certinfo,
- mkel(mkalg(sigalg),
- mkel(mkbits(buf, buflen),
- nil))));
- free(buf);
- if(encode(e, &certbytes) != ASN_OK)
- goto errret;
- if(certlen != nil)
- *certlen = certbytes->len;
- cert = (uchar*)certbytes;
- memmove(cert, certbytes->data, certbytes->len);
-errret:
- freevalfields(&e.val);
- free(subj);
- return cert;
-}
-
-uchar*
-X509rsareq(RSApriv *priv, char *subj, int *certlen)
-{
- /* RFC 2314, PKCS #10 Certification Request Syntax */
- int version = 0, sigalg = ALG_sha256WithRSAEncryption;
- uchar *cert = nil;
- Bytes *certbytes, *pkbytes, *certinfobytes, *sigbytes;
- Elem e, certinfo;
- DigestAlg *da;
- uchar digest[MAXdlen], *buf;
- int buflen;
- mpint *pkcs1;
- char *alts;
-
- if((pkbytes = encode_rsapubkey(&priv->pub)) == nil)
- return nil;
-
- subj = estrdup(subj);
- alts = splitalts(subj);
-
- e = mkseq(
- mkel(mkint(version),
- mkel(mkDN(subj),
- mkel(mkseq(
- mkel(mkalg(ALG_rsaEncryption),
- mkel(mkbits(pkbytes->data, pkbytes->len),
- nil))),
- mkextensions(alts, 1)))));
- freebytes(pkbytes);
- if(encode(e, &certinfobytes) != ASN_OK)
- goto errret;
- da = digestalg[sigalg];
- (*da->fun)(certinfobytes->data, certinfobytes->len, digest, 0);
- freebytes(certinfobytes);
- certinfo = e;
-
- sigbytes = encode_digest(da, digest);
- if(sigbytes == nil)
- goto errret;
- pkcs1 = pkcs1padbuf(sigbytes->data, sigbytes->len, priv->pub.n, 1);
- freebytes(sigbytes);
- if(pkcs1 == nil)
- goto errret;
-
- rsadecrypt(priv, pkcs1, pkcs1);
- buflen = mptobe(pkcs1, nil, 0, &buf);
- mpfree(pkcs1);
- e = mkseq(
- mkel(certinfo,
- mkel(mkalg(sigalg),
- mkel(mkbits(buf, buflen),
- nil))));
- free(buf);
- if(encode(e, &certbytes) != ASN_OK)
- goto errret;
- if(certlen != nil)
- *certlen = certbytes->len;
- cert = (uchar*)certbytes;
- memmove(cert, certbytes->data, certbytes->len);
-errret:
- freevalfields(&e.val);
- free(subj);
- return cert;
-}
-
-static void
-digestSPKI(int alg, uchar *pubkey, int npubkey, DigestState* (*fun)(uchar*, ulong, uchar*, DigestState*), uchar *digest)
-{
- Bytes *b = nil;
- Elem e = mkseq(mkel(mkalg(alg), mkel(mkbits(pubkey, npubkey), nil)));
- encode(e, &b);
- freevalfields(&e.val);
- (*fun)(b->data, b->len, digest, nil);
- freebytes(b);
-}
-
-int
-X509digestSPKI(uchar *cert, int ncert, DigestState* (*fun)(uchar*, ulong, uchar*, DigestState*), uchar *digest)
-{
- CertX509 *c;
-
- c = decode_cert(cert, ncert);
- if(c == nil){
- werrstr("cannot decode cert");
- return -1;
- }
- digestSPKI(c->publickey_alg, c->publickey->data, c->publickey->len, fun, digest);
- freecert(c);
- return 0;
-}
-
-static char*
-tagdump(Tag tag)
-{
- static char buf[32];
-
- if(tag.class != Universal){
- snprint(buf, sizeof(buf), "class%d,num%d", tag.class, tag.num);
- return buf;
- }
- switch(tag.num){
- case BOOLEAN: return "BOOLEAN";
- case INTEGER: return "INTEGER";
- case BIT_STRING: return "BIT STRING";
- case OCTET_STRING: return "OCTET STRING";
- case NULLTAG: return "NULLTAG";
- case OBJECT_ID: return "OID";
- case ObjectDescriptor: return "OBJECT_DES";
- case EXTERNAL: return "EXTERNAL";
- case REAL: return "REAL";
- case ENUMERATED: return "ENUMERATED";
- case EMBEDDED_PDV: return "EMBEDDED PDV";
- case SEQUENCE: return "SEQUENCE";
- case SETOF: return "SETOF";
- case UTF8String: return "UTF8String";
- case NumericString: return "NumericString";
- case PrintableString: return "PrintableString";
- case TeletexString: return "TeletexString";
- case VideotexString: return "VideotexString";
- case IA5String: return "IA5String";
- case UTCTime: return "UTCTime";
- case GeneralizedTime: return "GeneralizedTime";
- case GraphicString: return "GraphicString";
- case VisibleString: return "VisibleString";
- case GeneralString: return "GeneralString";
- case UniversalString: return "UniversalString";
- case BMPString: return "BMPString";
- default:
- snprint(buf, sizeof(buf), "Universal,num%d", tag.num);
- return buf;
- }
-}
-
-static void
-edump(Elem e)
-{
- Value v;
- Elist *el;
- int i;
-
- print("%s{", tagdump(e.tag));
- v = e.val;
- switch(v.tag){
- case VBool: print("Bool %d",v.u.boolval); break;
- case VInt: print("Int %d",v.u.intval); break;
- case VOctets: print("Octets[%d] %.2x%.2x...",v.u.octetsval->len,v.u.octetsval->data[0],v.u.octetsval->data[1]); break;
- case VBigInt: print("BigInt[%d] %.2x%.2x...",v.u.bigintval->len,v.u.bigintval->data[0],v.u.bigintval->data[1]); break;
- case VReal: print("Real..."); break;
- case VOther: print("Other..."); break;
- case VBitString: print("BitString[%d]...", v.u.bitstringval->len*8 - v.u.bitstringval->unusedbits); break;
- case VNull: print("Null"); break;
- case VEOC: print("EOC..."); break;
- case VObjId: print("ObjId");
- for(i = 0; i<v.u.objidval->len; i++)
- print(" %d", v.u.objidval->data[i]);
- break;
- case VString: print("String \"%s\"",v.u.stringval); break;
- case VSeq: print("Seq\n");
- for(el = v.u.seqval; el!=nil; el = el->tl)
- edump(el->hd);
- break;
- case VSet: print("Set\n");
- for(el = v.u.setval; el!=nil; el = el->tl)
- edump(el->hd);
- break;
- }
- print("}\n");
-}
-
-void
-asn1dump(uchar *der, int len)
-{
- Elem e;
-
- if(decode(der, len, &e) != ASN_OK){
- print("didn't parse\n");
- exits("didn't parse");
- }
- edump(e);
-}
-
-void
-X509dump(uchar *cert, int ncert)
-{
- char *e;
- CertX509 *c;
- RSApub *rsapub;
- ECpub *ecpub;
- ECdomain ecdom;
- int digestlen;
- uchar digest[MAXdlen];
-
- print("begin X509dump\n");
- c = decode_cert(cert, ncert);
- if(c == nil){
- print("cannot decode cert\n");
- return;
- }
-
- digestlen = digest_certinfo(cert, ncert, digestalg[c->signature_alg], digest);
- if(digestlen <= 0){
- freecert(c);
- print("cannot decode certinfo\n");
- return;
- }
-
- print("serial %d\n", c->serial);
- print("issuer %s\n", c->issuer);
- print("validity %s %s\n", c->validity_start, c->validity_end);
- print("subject %s\n", c->subject);
- print("sigalg=%d digest=%.*H\n", c->signature_alg, digestlen, digest);
- print("publickey_alg=%d pubkey[%d] %.*H\n", c->publickey_alg, c->publickey->len,
- c->publickey->len, c->publickey->data);
-
- switch(c->publickey_alg){
- case ALG_rsaEncryption:
- rsapub = asn1toRSApub(c->publickey->data, c->publickey->len);
- if(rsapub != nil){
- print("rsa pubkey e=%B n(%d)=%B\n", rsapub->ek, mpsignif(rsapub->n), rsapub->n);
- e = X509rsaverifydigest(c->signature->data, c->signature->len,
- digest, digestlen, rsapub);
- if(e==nil)
- e = "nil (meaning ok)";
- print("self-signed X509rsaverifydigest returns: %s\n", e);
- rsapubfree(rsapub);
- }
- break;
- case ALG_ecPublicKey:
- ecdominit(&ecdom, namedcurves[c->curve]);
- ecpub = ecdecodepub(&ecdom, c->publickey->data, c->publickey->len);
- if(ecpub != nil){
- e = X509ecdsaverifydigest(c->signature->data, c->signature->len,
- digest, digestlen, &ecdom, ecpub);
- if(e==nil)
- e = "nil (meaning ok)";
- print("self-signed X509ecdsaverifydigest returns: %s\n", e);
- ecpubfree(ecpub);
- }
- ecdomfree(&ecdom);
- break;
- }
-
- digestSPKI(c->publickey_alg, c->publickey->data, c->publickey->len, sha2_256, digest);
- print("publickey_thumbprint sha256=%.*[\n", SHA2_256dlen, digest);
-
- sha2_256(cert, ncert, digest, nil);
- print("cert_thumbprint sha256=%.*[\n", SHA2_256dlen, digest);
-
- sha1(cert, ncert, digest, nil);
- print("cert_thumbprint sha1=%.*H\n", SHA1dlen, digest);
-
- freecert(c);
- print("end X509dump\n");
-}
--- a/main.c
+++ b/main.c
@@ -4,11 +4,8 @@
#include "kern/fns.h"
#include "user.h"
#include "drawcpu.h"
-#include "ip.h"
-#include "authsrv.h"
char *argv0;
-char *authserver = "";
char *dbgfile = "./debug.log";
void
--- a/posix-factotum.c
+++ /dev/null
@@ -1,110 +1,0 @@
-#include <u.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <ctype.h>
-#include <pwd.h>
-#include <libc.h>
-#include <auth.h>
-#include <fcall.h>
-#include <authsrv.h>
-#include <libsec.h>
-#include "drawcpu.h"
-
-#undef socket
-#undef connect
-#undef getenv
-#undef access
-
-char*
-getuser(void)
-{
- static char user[64];
- struct passwd *pw;
-
- pw = getpwuid(getuid());
- if(pw == nil)
- return "none";
- strecpy(user, user+sizeof user, pw->pw_name);
- return user;
-}
-/*
- * Absent other hints, it works reasonably well to use
- * the X11 display name as the name space identifier.
- * This is how sam's B has worked since the early days.
- * Since most programs using name spaces are also using X,
- * this still seems reasonable. Terminal-only sessions
- * can set $NAMESPACE.
- */
-static char*
-nsfromdisplay(void)
-{
- char *disp, *p;
-
- if((disp = getenv("DISPLAY")) == nil){
- werrstr("$DISPLAY not set");
- return nil;
- }
-
- /* canonicalize: xxx:0.0 => xxx:0 */
- p = strrchr(disp, ':');
- if(p){
- p++;
- while(isdigit((uchar)*p))
- p++;
- if(strcmp(p, ".0") == 0)
- *p = 0;
- }
-
- return smprint("/tmp/ns.%s.%s", getuser(), disp);
-}
-
-char*
-getns(void)
-{
- char *ns;
-
- ns = getenv("NAMESPACE");
- if(ns == nil)
- ns = nsfromdisplay();
- if(ns == nil){
- werrstr("$NAMESPACE not set, %r");
- return nil;
- }
- return ns;
-}
-
-int
-dialfactotum(void)
-{
- int fd;
- struct sockaddr_un su;
- char *name;
-
- name = smprint("%s/factotum", getns());
-
- if(name == nil || access(name, 0) < 0)
- goto err;
- memset(&su, 0, sizeof su);
- su.sun_family = AF_UNIX;
- if(strlen(name)+1 > sizeof su.sun_path){
- werrstr("socket name too long");
- goto err;
- }
- strcpy(su.sun_path, name);
- if((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
- werrstr("socket: %r");
- goto err;
- }
- if(connect(fd, (struct sockaddr*)&su, sizeof su) < 0){
- werrstr("connect %s: %r", name);
- close(fd);
- goto err;
- }
-
- free(name);
- return lfdfd(fd);
-err:
- free(name);
- return -1;
-}
-
--- a/rc/glob.c
+++ b/rc/glob.c
@@ -51,7 +51,7 @@
static int
matchfn(char *s, char *p)
{
- if(s[0]=='.' && (s[1]=='\0' || s[1]=='.' && s[2]=='\0') && p[0]!='.')
+ if(s[0]=='.' && ((s[1]=='\0' || s[1]=='.') && s[2]=='\0') && p[0]!='.')
return 0;
return match(s, p, '/');
}
--- a/rc/lex.c
+++ b/rc/lex.c
@@ -352,8 +352,8 @@
t->rtype = CLOSE;
}
}
- if(c!=']'
- || t->type==DUP && (t->rtype==HERE || t->rtype==APPEND))
+ if((c!=']'
+ || t->type==DUP) && (t->rtype==HERE || t->rtype==APPEND))
goto RedirErr;
*w++=']';
}
--- a/rc/simple.c
+++ b/rc/simple.c
@@ -151,7 +151,7 @@
word *path;
if(w[0] && w[0] != '/' && w[0] != '#' &&
- (w[0] != '.' || (w[1] && w[1] != '/' && (w[1] != '.' || w[2] && w[2] != '/')))){
+ (w[0] != '.' || (w[1] && w[1] != '/' && (w[1] != '.' || (w[2] && w[2] != '/'))))){
path = vlook(v)->val;
if(path)
return path;
@@ -340,7 +340,7 @@
popword();
}
}
- if(count(runq->argv->words)!=2 || (flag&MAFTER)&&(flag&MBEFORE))
+ if(count(runq->argv->words)!=2 || ((flag & MAFTER) && (flag & MBEFORE)))
goto Usage;
if(bind(runq->argv->words->word, runq->argv->words->next->word, flag) == -1)
goto Error;
@@ -729,7 +729,7 @@
pushredir(RCLOSE, fd, 0);
runq->lex->qflag = qflag;
runq->iflag = iflag;
- if(iflag || !bflag && flag['b']==0){
+ if(iflag || (!bflag && flag['b']==0)){
runq->lex->peekc=EOF;
runq->lex->epilog="";
}
--- a/secstore.c
+++ /dev/null
@@ -1,668 +1,0 @@
-/*
- * Various files from /sys/src/cmd/auth/secstore, just enough
- * to download a file at boot time.
- */
-
-#include <u.h>
-#include <libc.h>
-#include <mp.h>
-#include <libsec.h>
-#include <authsrv.h>
-#include "drawcpu.h"
-
-static void*
-emalloc(ulong n)
-{
- return mallocz(n, 1);
-}
-
-enum{ CHK = 16};
-enum{ MAXFILESIZE = 10*1024*1024 };
-
-enum{// PW status bits
- Enabled = (1<<0),
- STA = (1<<1), // extra SecurID step
-};
-
-static char testmess[] = "__secstore\tPAK\nC=%s\nm=0\n";
-
-int
-secdial(char *secstore)
-{
- char *p, buf[80], *f[3];
- int fd, nf;
-
- p = secstore; /* take it from writehostowner, if set there */
- if(*p == 0) /* else use the authserver */
- p = "$auth";
-
- /* translate $auth ourselves.
- * authaddr is something like il!host!566 or tcp!host!567.
- * extract host, accounting for a change of format to something
- * like il!host or tcp!host or host.
- */
- if(strcmp(p, "$auth")==0){
- if(authserver == nil)
- return -1;
- strecpy(buf, buf+sizeof buf, authserver);
- nf = getfields(buf, f, nelem(f), 0, "!");
- switch(nf){
- default:
- return -1;
- case 1:
- p = f[0];
- break;
- case 2:
- case 3:
- p = f[1];
- break;
- }
- }
- fd = dial(netmkaddr(p, "tcp", "secstore"), 0, 0, 0);
- if(fd >= 0)
- return fd;
- return -1;
-}
-
-int
-havesecstore(char *addr, char *owner)
-{
- int m, n, fd;
- uchar buf[500];
-
- n = snprint((char*)buf, sizeof buf, testmess, owner);
- hnputs(buf, 0x8000+n-2);
-
- fd = secdial(addr);
- if(fd < 0)
- return 0;
- if(write(fd, buf, n) != n || readn(fd, buf, 2) != 2){
- close(fd);
- return 0;
- }
- n = ((buf[0]&0x7f)<<8) + buf[1];
- if(n+1 > sizeof buf){
- werrstr("implausibly large count %d", n);
- close(fd);
- return 0;
- }
- m = readn(fd, buf, n);
- close(fd);
- if(m != n){
- if(m >= 0)
- werrstr("short read from secstore");
- return 0;
- }
- buf[n] = 0;
- if(strcmp((char*)buf, "!account expired") == 0){
- werrstr("account expired");
- return 0;
- }
- return strcmp((char*)buf, "!account exists") == 0;
-}
-
-// delimited, authenticated, encrypted connection
-enum{ Maxmsg=4096 }; // messages > Maxmsg bytes are truncated
-typedef struct SConn SConn;
-
-extern SConn* newSConn(int); // arg is open file descriptor
-struct SConn{
- void *chan;
- int secretlen;
- int (*secret)(SConn*, uchar*, int);//
- int (*read)(SConn*, uchar*, int); // <0 if error; errmess in buffer
- int (*write)(SConn*, uchar*, int);
- void (*free)(SConn*); // also closes file descriptor
-};
-// secret(s,b,dir) sets secret for digest, encrypt, using the secretlen
-// bytes in b to form keys for the two directions;
-// set dir=0 in client, dir=1 in server
-
-// error convention: write !message in-band
-#define readstr secstore_readstr
-static void writerr(SConn*, char*);
-static int readstr(SConn*, char*); // call with buf of size Maxmsg+1
- // returns -1 upon error, with error message in buf
-
-typedef struct ConnState {
- uchar secret[SHA1dlen];
- ulong seqno;
- RC4state rc4;
-} ConnState;
-
-typedef struct SS{
- int fd; // file descriptor for read/write of encrypted data
- int alg; // if nonzero, "alg sha rc4_128"
- ConnState in, out;
-} SS;
-
-static int
-SC_secret(SConn *conn, uchar *sigma, int direction)
-{
- SS *ss = (SS*)(conn->chan);
- int nsigma = conn->secretlen;
-
- if(direction != 0){
- hmac_sha1(sigma, nsigma, (uchar*)"one", 3, ss->out.secret, nil);
- hmac_sha1(sigma, nsigma, (uchar*)"two", 3, ss->in.secret, nil);
- }else{
- hmac_sha1(sigma, nsigma, (uchar*)"two", 3, ss->out.secret, nil);
- hmac_sha1(sigma, nsigma, (uchar*)"one", 3, ss->in.secret, nil);
- }
- setupRC4state(&ss->in.rc4, ss->in.secret, 16); // restrict to 128 bits
- setupRC4state(&ss->out.rc4, ss->out.secret, 16);
- ss->alg = 1;
- return 0;
-}
-
-static void
-hash(uchar secret[SHA1dlen], uchar *data, int len, int seqno, uchar d[SHA1dlen])
-{
- DigestState sha;
- uchar seq[4];
-
- seq[0] = seqno>>24;
- seq[1] = seqno>>16;
- seq[2] = seqno>>8;
- seq[3] = seqno;
- memset(&sha, 0, sizeof sha);
- sha1(secret, SHA1dlen, nil, &sha);
- sha1(data, len, nil, &sha);
- sha1(seq, 4, d, &sha);
-}
-
-static int
-verify(uchar secret[SHA1dlen], uchar *data, int len, int seqno, uchar d[SHA1dlen])
-{
- DigestState sha;
- uchar seq[4];
- uchar digest[SHA1dlen];
-
- seq[0] = seqno>>24;
- seq[1] = seqno>>16;
- seq[2] = seqno>>8;
- seq[3] = seqno;
- memset(&sha, 0, sizeof sha);
- sha1(secret, SHA1dlen, nil, &sha);
- sha1(data, len, nil, &sha);
- sha1(seq, 4, digest, &sha);
- return tsmemcmp(d, digest, SHA1dlen);
-}
-
-static int
-SC_read(SConn *conn, uchar *buf, int n)
-{
- SS *ss = (SS*)(conn->chan);
- uchar count[2], digest[SHA1dlen];
- int len, nr;
-
- if(read(ss->fd, count, 2) != 2 || (count[0]&0x80) == 0){
- werrstr("!SC_read invalid count");
- return -1;
- }
- len = (count[0]&0x7f)<<8 | count[1]; // SSL-style count; no pad
- if(ss->alg){
- len -= SHA1dlen;
- if(len <= 0 || readn(ss->fd, digest, SHA1dlen) != SHA1dlen){
- werrstr("!SC_read missing sha1");
- return -1;
- }
- if(len > n || readn(ss->fd, buf, len) != len){
- werrstr("!SC_read missing data");
- return -1;
- }
- rc4(&ss->in.rc4, digest, SHA1dlen);
- rc4(&ss->in.rc4, buf, len);
- if(verify(ss->in.secret, buf, len, ss->in.seqno, digest) != 0){
- werrstr("!SC_read integrity check failed");
- return -1;
- }
- }else{
- if(len <= 0 || len > n){
- werrstr("!SC_read implausible record length");
- return -1;
- }
- if( (nr = readn(ss->fd, buf, len)) != len){
- werrstr("!SC_read expected %d bytes, but got %d", len, nr);
- return -1;
- }
- }
- ss->in.seqno++;
- return len;
-}
-
-static int
-SC_write(SConn *conn, uchar *buf, int n)
-{
- SS *ss = (SS*)(conn->chan);
- uchar count[2], digest[SHA1dlen];
- int len;
-
- if(n <= 0 || n > Maxmsg+1){
- werrstr("!SC_write invalid n %d", n);
- return -1;
- }
- len = n;
- if(ss->alg)
- len += SHA1dlen;
- count[0] = 0x80 | len>>8;
- count[1] = len;
- if(write(ss->fd, count, 2) != 2){
- werrstr("!SC_write invalid count");
- return -1;
- }
- if(ss->alg){
- hash(ss->out.secret, buf, n, ss->out.seqno, digest);
- rc4(&ss->out.rc4, digest, SHA1dlen);
- rc4(&ss->out.rc4, buf, n);
- if(write(ss->fd, digest, SHA1dlen) != SHA1dlen ||
- write(ss->fd, buf, n) != n){
- werrstr("!SC_write error on send");
- return -1;
- }
- }else{
- if(write(ss->fd, buf, n) != n){
- werrstr("!SC_write error on send");
- return -1;
- }
- }
- ss->out.seqno++;
- return n;
-}
-
-static void
-SC_free(SConn *conn)
-{
- SS *ss = (SS*)(conn->chan);
-
- close(ss->fd);
- free(ss);
- free(conn);
-}
-
-SConn*
-newSConn(int fd)
-{
- SS *ss;
- SConn *conn;
-
- if(fd < 0)
- return nil;
- ss = (SS*)emalloc(sizeof(*ss));
- conn = (SConn*)emalloc(sizeof(*conn));
- ss->fd = fd;
- ss->alg = 0;
- conn->chan = (void*)ss;
- conn->secretlen = SHA1dlen;
- conn->free = SC_free;
- conn->secret = SC_secret;
- conn->read = SC_read;
- conn->write = SC_write;
- return conn;
-}
-
-static void
-writerr(SConn *conn, char *s)
-{
- char buf[Maxmsg];
-
- snprint(buf, Maxmsg, "!%s", s);
- conn->write(conn, (uchar*)buf, strlen(buf));
-}
-
-static int
-readstr(SConn *conn, char *s)
-{
- int n;
-
- n = conn->read(conn, (uchar*)s, Maxmsg);
- if(n >= 0){
- s[n] = 0;
- if(s[0] == '!'){
- memmove(s, s+1, n);
- n = -1;
- }
- }else{
- strcpy(s, "read error");
- }
- return n;
-}
-
-static char*
-getfile(SConn *conn, uchar *key, int nkey)
-{
- char *buf;
- int nbuf, n, nr, len;
- char s[Maxmsg+1], *gf;
- uchar skey[SHA1dlen], ib[Maxmsg+CHK], *ibr, *ibw;
- AESstate aes;
- DigestState *sha;
-
- gf = "factotum";
- memset(&aes, 0, sizeof aes);
-
- snprint(s, Maxmsg, "GET %s\n", gf);
- conn->write(conn, (uchar*)s, strlen(s));
-
- /* get file size */
- s[0] = '\0';
- if(readstr(conn, s) < 0){
- werrstr("secstore: %r");
- return nil;
- }
- if((len = atoi(s)) < 0){
- werrstr("secstore: remote file %s does not exist", gf);
- return nil;
- }else if(len > MAXFILESIZE){//assert
- werrstr("secstore: implausible file size %d for %s", len, gf);
- return nil;
- }
-
- ibr = ibw = ib;
- buf = nil;
- nbuf = 0;
- for(nr=0; nr < len;){
- if((n = conn->read(conn, ibw, Maxmsg)) <= 0){
- werrstr("secstore: empty file chunk n=%d nr=%d len=%d: %r", n, nr, len);
- return nil;
- }
- nr += n;
- ibw += n;
- if(!aes.setup){ /* first time, read 16 byte IV */
- if(n < 16){
- werrstr("secstore: no IV in file");
- return nil;
- }
- sha = sha1((uchar*)"aescbc file", 11, nil, nil);
- sha1(key, nkey, skey, sha);
- setupAESstate(&aes, skey, AESbsize, ibr);
- memset(skey, 0, sizeof skey);
- ibr += AESbsize;
- n -= AESbsize;
- }
- aesCBCdecrypt(ibw-n, n, &aes);
- n = ibw-ibr-CHK;
- if(n > 0){
- buf = realloc(buf, nbuf+n+1);
- if(buf == nil)
- sysfatal("out of memory");
- memmove(buf+nbuf, ibr, n);
- nbuf += n;
- ibr += n;
- }
- memmove(ib, ibr, ibw-ibr);
- ibw = ib + (ibw-ibr);
- ibr = ib;
- }
- n = ibw-ibr;
- if((n != CHK) || (memcmp(ib, "XXXXXXXXXXXXXXXX", CHK) != 0)){
- werrstr("secstore: decrypted file failed to authenticate!");
- free(buf);
- return nil;
- }
- if(nbuf == 0){
- werrstr("secstore got empty file");
- return nil;
- }
- buf[nbuf] = '\0';
- return buf;
-}
-
-static char VERSION[] = "secstore";
-
-typedef struct PAKparams{
- mpint *q, *p, *r, *g;
-} PAKparams;
-
-static PAKparams *pak;
-
-// This group was generated by the seed EB7B6E35F7CD37B511D96C67D6688CC4DD440E1E.
-static void
-initPAKparams(void)
-{
- if(pak)
- return;
- pak = (PAKparams*)emalloc(sizeof(*pak));
- pak->q = strtomp("E0F0EF284E10796C5A2A511E94748BA03C795C13", nil, 16, nil);
- pak->p = strtomp("C41CFBE4D4846F67A3DF7DE9921A49D3B42DC33728427AB159CEC8CBBD"
- "B12B5F0C244F1A734AEB9840804EA3C25036AD1B61AFF3ABBC247CD4B384224567A86"
- "3A6F020E7EE9795554BCD08ABAD7321AF27E1E92E3DB1C6E7E94FAAE590AE9C48F96D9"
- "3D178E809401ABE8A534A1EC44359733475A36A70C7B425125062B1142D", nil, 16, nil);
- pak->r = strtomp("DF310F4E54A5FEC5D86D3E14863921E834113E060F90052AD332B3241CEF"
- "2497EFA0303D6344F7C819691A0F9C4A773815AF8EAECFB7EC1D98F039F17A32A7E887"
- "D97251A927D093F44A55577F4D70444AEBD06B9B45695EC23962B175F266895C67D21"
- "C4656848614D888A4", nil, 16, nil);
- pak->g = strtomp("2F1C308DC46B9A44B52DF7DACCE1208CCEF72F69C743ADD4D2327173444"
- "ED6E65E074694246E07F9FD4AE26E0FDDD9F54F813C40CB9BCD4338EA6F242AB94CD41"
- "0E676C290368A16B1A3594877437E516C53A6EEE5493A038A017E955E218E7819734E3E"
- "2A6E0BAE08B14258F8C03CC1B30E0DDADFCF7CEDF0727684D3D255F1", nil, 16, nil);
-}
-
-// H = (sha(ver,C,sha(passphrase)))^r mod p,
-// a hash function expensive to attack by brute force.
-static void
-longhash(char *ver, char *C, uchar *passwd, mpint *H)
-{
- uchar *Cp;
- int i, n, nver, nC;
- uchar buf[140], key[1];
-
- nver = strlen(ver);
- nC = strlen(C);
- n = nver + nC + SHA1dlen;
- Cp = (uchar*)emalloc(n);
- memmove(Cp, ver, nver);
- memmove(Cp+nver, C, nC);
- memmove(Cp+nver+nC, passwd, SHA1dlen);
- for(i = 0; i < 7; i++){
- key[0] = 'A'+i;
- hmac_sha1(Cp, n, key, sizeof key, buf+i*SHA1dlen, nil);
- }
- memset(Cp, 0, n);
- free(Cp);
- betomp(buf, sizeof buf, H);
- mpmod(H, pak->p, H);
- mpexp(H, pak->r, pak->p, H);
-}
-
-// Hi = H^-1 mod p
-static char *
-PAK_Hi(char *C, char *passphrase, mpint *H, mpint *Hi)
-{
- uchar passhash[SHA1dlen];
-
- sha1((uchar *)passphrase, strlen(passphrase), passhash, nil);
- initPAKparams();
- longhash(VERSION, C, passhash, H);
- mpinvert(H, pak->p, Hi);
- return mptoa(Hi, 64, nil, 0);
-}
-
-// another, faster, hash function for each party to
-// confirm that the other has the right secrets.
-static void
-shorthash(char *mess, char *C, char *S, char *m, char *mu, char *sigma, char *Hi, uchar *digest)
-{
- SHA1state *state;
-
- state = sha1((uchar*)mess, strlen(mess), 0, 0);
- state = sha1((uchar*)C, strlen(C), 0, state);
- state = sha1((uchar*)S, strlen(S), 0, state);
- state = sha1((uchar*)m, strlen(m), 0, state);
- state = sha1((uchar*)mu, strlen(mu), 0, state);
- state = sha1((uchar*)sigma, strlen(sigma), 0, state);
- state = sha1((uchar*)Hi, strlen(Hi), 0, state);
- state = sha1((uchar*)mess, strlen(mess), 0, state);
- state = sha1((uchar*)C, strlen(C), 0, state);
- state = sha1((uchar*)S, strlen(S), 0, state);
- state = sha1((uchar*)m, strlen(m), 0, state);
- state = sha1((uchar*)mu, strlen(mu), 0, state);
- state = sha1((uchar*)sigma, strlen(sigma), 0, state);
- sha1((uchar*)Hi, strlen(Hi), digest, state);
-}
-
-// On input, conn provides an open channel to the server;
-// C is the name this client calls itself;
-// pass is the user's passphrase
-// On output, session secret has been set in conn
-// (unless return code is negative, which means failure).
-// If pS is not nil, it is set to the (alloc'd) name the server calls itself.
-static int
-PAKclient(SConn *conn, char *C, char *pass, char **pS)
-{
- char *mess, *mess2, *eol, *S, *hexmu, *ks, *hexm, *hexsigma = nil, *hexHi;
- char kc[2*SHA1dlen+1];
- uchar digest[SHA1dlen];
- int rc = -1, n;
- mpint *x, *m = mpnew(0), *mu = mpnew(0), *sigma = mpnew(0);
- mpint *H = mpnew(0), *Hi = mpnew(0);
-
- hexHi = PAK_Hi(C, pass, H, Hi);
-
- // random 1<=x<=q-1; send C, m=g**x H
- x = mprand(164, genrandom, nil);
- mpmod(x, pak->q, x);
- if(mpcmp(x, mpzero) == 0)
- mpassign(mpone, x);
- mpexp(pak->g, x, pak->p, m);
- mpmul(m, H, m);
- mpmod(m, pak->p, m);
- hexm = mptoa(m, 64, nil, 0);
- mess = (char*)emalloc(2*Maxmsg+2);
- mess2 = mess+Maxmsg+1;
- snprint(mess, Maxmsg, "%s\tPAK\nC=%s\nm=%s\n", VERSION, C, hexm);
- conn->write(conn, (uchar*)mess, strlen(mess));
-
- // recv g**y, S, check hash1(g**xy)
- if(readstr(conn, mess) < 0){
- fprint(2, "error: %s\n", mess);
- writerr(conn, "couldn't read g**y");
- goto done;
- }
- eol = strchr(mess, '\n');
- if(strncmp("mu=", mess, 3) != 0 || !eol || strncmp("\nk=", eol, 3) != 0){
- writerr(conn, "verifier syntax error");
- goto done;
- }
- hexmu = mess+3;
- *eol = 0;
- ks = eol+3;
- eol = strchr(ks, '\n');
- if(!eol || strncmp("\nS=", eol, 3) != 0){
- writerr(conn, "verifier syntax error for secstore 1.0");
- goto done;
- }
- *eol = 0;
- S = eol+3;
- eol = strchr(S, '\n');
- if(!eol){
- writerr(conn, "verifier syntax error for secstore 1.0");
- goto done;
- }
- *eol = 0;
- if(pS)
- *pS = estrdup(S);
- strtomp(hexmu, nil, 64, mu);
- mpexp(mu, x, pak->p, sigma);
- hexsigma = mptoa(sigma, 64, nil, 0);
- shorthash("server", C, S, hexm, hexmu, hexsigma, hexHi, digest);
- enc64(kc, sizeof kc, digest, SHA1dlen);
- if(strcmp(ks, kc) != 0){
- writerr(conn, "verifier didn't match");
- goto done;
- }
-
- // send hash2(g**xy)
- shorthash("client", C, S, hexm, hexmu, hexsigma, hexHi, digest);
- enc64(kc, sizeof kc, digest, SHA1dlen);
- snprint(mess2, Maxmsg, "k'=%s\n", kc);
- conn->write(conn, (uchar*)mess2, strlen(mess2));
-
- // set session key
- shorthash("session", C, S, hexm, hexmu, hexsigma, hexHi, digest);
- memset(hexsigma, 0, strlen(hexsigma));
- n = conn->secret(conn, digest, 0);
- memset(digest, 0, SHA1dlen);
- if(n < 0){//assert
- writerr(conn, "can't set secret");
- goto done;
- }
-
- rc = 0;
-done:
- mpfree(x);
- mpfree(sigma);
- mpfree(mu);
- mpfree(m);
- mpfree(Hi);
- mpfree(H);
- free(hexsigma);
- free(hexHi);
- free(hexm);
- free(mess);
- return rc;
-}
-
-char*
-secstorefetch(char *addr, char *owner, char *password)
-{
- int fd;
- char *rv;
- char s[Maxmsg+1], bye[10];
- SConn *conn;
- char *pass, *sta;
-
- sta = nil;
- conn = nil;
- rv = nil;
- if(password != nil && *password)
- pass = estrdup(password);
- else
- pass = readcons("secstore password", nil, 1);
- if(pass==nil || strlen(pass)==0){
- werrstr("cancel");
- goto Out;
- }
- if((fd = secdial(addr)) < 0)
- goto Out;
- if((conn = newSConn(fd)) == nil)
- goto Out;
- if(PAKclient(conn, owner, pass, nil) < 0){
- werrstr("password mistyped?");
- goto Out;
- }
- if(readstr(conn, s) < 0)
- goto Out;
- if(strcmp(s, "STA") == 0){
- sta = readcons("STA PIN+SecureID", nil, 1);
- if(sta==nil || strlen(sta)==0){
- werrstr("cancel");
- goto Out;
- }
- if(strlen(sta) >= sizeof s - 3){
- werrstr("STA response too long");
- goto Out;
- }
- strcpy(s+3, sta);
- conn->write(conn, (uchar*)s, strlen(s));
- readstr(conn, s);
- }
- if(strcmp(s, "OK") !=0){
- werrstr("%s", s);
- goto Out;
- }
- if((rv = getfile(conn, (uchar*)pass, strlen(pass))) == nil)
- goto Out;
- strcpy(bye, "BYE");
- conn->write(conn, (uchar*)bye, 3);
-
-Out:
- if(conn)
- conn->free(conn);
- if(pass)
- free(pass);
- if(sta)
- free(sta);
- return rv;
-}
-
--- a/win32-factotum.c
+++ /dev/null
@@ -1,22 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <auth.h>
-#include <fcall.h>
-#include <authsrv.h>
-#include <libsec.h>
-#include "drawcpu.h"
-
-#undef getenv
-
-char*
-getuser(void)
-{
- return getenv("USER");
-}
-
-int
-dialfactotum(void)
-{
- return -1;
-}
-
--- a/win32-ip.c
+++ /dev/null
@@ -1,1 +1,0 @@
-//TODO: I don't want to do this, if anyone wants into windows we need the pm_announce, pm_listen and pm_accept filled out
\ No newline at end of file