]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libsec/port/ccpoly.c
libsec: implement SPKI fingerprinting for okCertificate()
[plan9front.git] / sys / src / libsec / port / ccpoly.c
1 #include "os.h"
2 #include <libsec.h>
3
4 static void
5 ccpolyotk(Chachastate *cs, DigestState *ds)
6 {
7         uchar otk[ChachaBsize];
8
9         memset(ds, 0, sizeof(*ds));
10         memset(otk, 0, 32);
11         chacha_setblock(cs, 0);
12         chacha_encrypt(otk, ChachaBsize, cs);
13         poly1305(nil, 0, otk, 32, nil, ds);
14 }
15
16 static void
17 ccpolypad(uchar *buf, ulong nbuf, DigestState *ds)
18 {
19         static uchar zeros[16] = {0};
20         ulong npad;
21
22         if(nbuf == 0)
23                 return;
24         poly1305(buf, nbuf, nil, 0, nil, ds);
25         npad = nbuf % 16;
26         if(npad == 0)
27                 return;
28         poly1305(zeros, 16 - npad, nil, 0, nil, ds);
29 }
30
31 static void
32 ccpolylen(ulong n, uchar tag[16], DigestState *ds)
33 {
34         uchar info[8];
35
36         info[0] = n;
37         info[1] = n>>8;
38         info[2] = n>>16;
39         info[3] = n>>24;
40         info[4] = 0;
41         info[5] = 0;
42         info[6] = 0;
43         info[7] = 0;
44         poly1305(info, 8, nil, 0, tag, ds);
45 }
46
47 void
48 ccpoly_encrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], Chachastate *cs)
49 {
50         DigestState ds;
51
52         ccpolyotk(cs, &ds);
53         if(cs->ivwords == 2){
54                 poly1305(aad, naad, nil, 0, nil, &ds);
55                 ccpolylen(naad, nil, &ds);
56                 chacha_encrypt(dat, ndat, cs);
57                 poly1305(dat, ndat, nil, 0, nil, &ds);
58                 ccpolylen(ndat, tag, &ds);
59         } else {
60                 ccpolypad(aad, naad, &ds);
61                 chacha_encrypt(dat, ndat, cs);
62                 ccpolypad(dat, ndat, &ds);
63                 ccpolylen(naad, nil, &ds);
64                 ccpolylen(ndat, tag, &ds);
65         }
66 }
67
68 int
69 ccpoly_decrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], Chachastate *cs)
70 {
71         DigestState ds;
72         uchar tmp[16];
73
74         ccpolyotk(cs, &ds);
75         if(cs->ivwords == 2){
76                 poly1305(aad, naad, nil, 0, nil, &ds);
77                 ccpolylen(naad, nil, &ds);
78                 poly1305(dat, ndat, nil, 0, nil, &ds);
79                 ccpolylen(ndat, tmp, &ds);
80         } else {
81                 ccpolypad(aad, naad, &ds);
82                 ccpolypad(dat, ndat, &ds);
83                 ccpolylen(naad, nil, &ds);
84                 ccpolylen(ndat, tmp, &ds);
85         }
86         if(tsmemcmp(tag, tmp, 16) != 0)
87                 return -1;
88         chacha_encrypt(dat, ndat, cs);
89         return 0;
90 }