]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libauthsrv/form1.c
upas/marshal: fix printinreplyto function
[plan9front.git] / sys / src / libauthsrv / form1.c
1 #include <u.h>
2 #include <libc.h>
3 #include <authsrv.h>
4 #include <libsec.h>
5
6 /*
7  * new ticket format: the reply protector/type is replaced by a
8  * 8 byte signature and a 4 byte counter forming the 12 byte
9  * nonce for chacha20/poly1305 encryption. a 16 byte poly1305 
10  * authentication tag is appended for message authentication.
11  * the counter is needed for the AuthPass message which uses
12  * the same key for several messages.
13  */
14
15 static struct {
16         char    num;
17         char    sig[8];
18 } form1sig[] = {
19         AuthPass,       "form1 PR",     /* password change request encrypted with ticket key */
20         AuthTs,         "form1 Ts",     /* ticket encrypted with server's key */
21         AuthTc,         "form1 Tc",     /* ticket encrypted with client's key */
22         AuthAs,         "form1 As",     /* server generated authenticator */
23         AuthAc,         "form1 Ac",     /* client generated authenticator */
24         AuthTp,         "form1 Tp",     /* ticket encrypted with client's key for password change */
25         AuthHr,         "form1 Hr",     /* http reply */
26 };
27
28 int
29 form1check(char *ap, int n)
30 {
31         if(n < 8)
32                 return -1;
33
34         for(n=0; n<nelem(form1sig); n++)
35                 if(memcmp(form1sig[n].sig, ap, 8) == 0)
36                         return form1sig[n].num;
37
38         return -1;
39 }
40
41 int
42 form1B2M(char *ap, int n, uchar key[32])
43 {
44         static u32int counter;
45         Chachastate s;
46         uchar *p;
47         int i;
48
49         for(i=nelem(form1sig)-1; i>=0; i--)
50                 if(form1sig[i].num == *ap)
51                         break;
52         if(i < 0)
53                 abort();
54
55         p = (uchar*)ap + 12;
56         memmove(p, ap+1, --n);
57
58         /* nonce[12] = sig[8] | counter[4] */
59         memmove(ap, form1sig[i].sig, 8);
60         i = counter++;
61         ap[8] = i, ap[9] = i>>8, ap[10] = i>>16, ap[11] = i>>24;
62
63         setupChachastate(&s, key, 32, (uchar*)ap, 12, 20);
64         ccpoly_encrypt(p, n, nil, 0, p+n, &s);
65         return 12+16 + n;
66 }
67
68 int
69 form1M2B(char *ap, int n, uchar key[32])
70 {
71         Chachastate s;
72         uchar *p;
73         int num;
74
75         num = form1check(ap, n);
76         if(num < 0)
77                 return -1;
78         n -= 12+16;
79         if(n <= 0)
80                 return -1;
81
82         p = (uchar*)ap + 12;
83         setupChachastate(&s, key, 32, (uchar*)ap, 12, 20);
84         if(ccpoly_decrypt(p, n, nil, 0, p+n, &s))
85                 return -1;
86
87         memmove(ap+1, p, n);
88         ap[0] = num;
89         return n+1;
90 }