add ccm mode from cinap Reference: /n/atom/patch/applied/aesccm Date: Thu May 15 00:46:00 CES 2014 Signed-off-by: quanstro@quanstro.net --- /sys/src/libsec/port/aesccm.c Thu Jan 1 00:00:00 1970 +++ /sys/src/libsec/port/aesccm.c Thu May 15 00:45:59 2014 @@ -0,0 +1,125 @@ +#include +#include +#include +#include + +static uchar* +putbe32(uchar *p, u32int v, int L) +{ + while(--L >= 0) + *p++ = v >> L*8; + return p; +} + +static void +xblock(int L, int M, uchar *N, uchar *a, int la, int lm, uchar t[16], AESstate *s) +{ + uchar l[8], *p, *x, *e; + + assert(M >= 4 && M <= 16); + assert(L >= 2 && L <= 4); + + t[0] = ((la > 0)<<6) | ((M-2)/2)<<3 | (L-1); /* flags */ + memmove(&t[1], N, 15-L); + putbe32(&t[16-L], lm, L); + aes_encrypt(s->ekey, s->rounds, t, t); + + if(la > 0){ + assert(la < 0xFF00); + for(p = l, e = putbe32(l, la, 2), x = t; p < e; x++, p++) + *x ^= *p; + for(e = a + la; a < e; x = t){ + for(; a < e && x < &t[16]; x++, a++) + *x ^= *a; + aes_encrypt(s->ekey, s->rounds, t, t); + } + } +} + +static uchar* +sblock(int L, uchar *N, uint i, uchar b[16], AESstate *s) +{ + b[0] = L-1; /* flags */ + memmove(&b[1], N, 15-L); + putbe32(&b[16-L], i, L); + aes_encrypt(s->ekey, s->rounds, b, b); + return b; +}; + +void +aesCCMencrypt(int L, int M, uchar *N /* N[15-L] */, + uchar *a /* a[la] */, int la, + uchar *m /* m[lm+M] */, int lm, + AESstate *s) +{ + uchar t[16], b[16], *p, *x; + uint i; + + xblock(L, M, N, a, la, lm, t, s); + + for(i = 1; lm >= 16; i++, m += 16, lm -= 16){ + sblock(L, N, i, b, s); + + *((u32int*)&t[0]) ^= *((u32int*)&m[0]); + *((u32int*)&m[0]) ^= *((u32int*)&b[0]); + *((u32int*)&t[4]) ^= *((u32int*)&m[4]); + *((u32int*)&m[4]) ^= *((u32int*)&b[4]); + *((u32int*)&t[8]) ^= *((u32int*)&m[8]); + *((u32int*)&m[8]) ^= *((u32int*)&b[8]); + *((u32int*)&t[12]) ^= *((u32int*)&m[12]); + *((u32int*)&m[12]) ^= *((u32int*)&b[12]); + + aes_encrypt(s->ekey, s->rounds, t, t); + } + if(lm > 0){ + for(p = sblock(L, N, i, b, s), x = t; p < &b[lm]; x++, m++, p++){ + *x ^= *m; + *m ^= *p; + } + aes_encrypt(s->ekey, s->rounds, t, t); + } + + for(p = sblock(L, N, 0, b, s), x = t; p < &b[M]; x++, p++) + *x ^= *p; + + memmove(m, t, M); +} + +int +aesCCMdecrypt(int L, int M, uchar *N /* N[15-L] */, + uchar *a /* a[la] */, int la, + uchar *m /* m[lm+M] */, int lm, + AESstate *s) +{ + uchar t[16], b[16], *p, *x; + uint i; + + xblock(L, M, N, a, la, lm, t, s); + + for(i = 1; lm >= 16; i++, m += 16, lm -= 16){ + sblock(L, N, i, b, s); + + *((u32int*)&m[0]) ^= *((u32int*)&b[0]); + *((u32int*)&t[0]) ^= *((u32int*)&m[0]); + *((u32int*)&m[4]) ^= *((u32int*)&b[4]); + *((u32int*)&t[4]) ^= *((u32int*)&m[4]); + *((u32int*)&m[8]) ^= *((u32int*)&b[8]); + *((u32int*)&t[8]) ^= *((u32int*)&m[8]); + *((u32int*)&m[12]) ^= *((u32int*)&b[12]); + *((u32int*)&t[12]) ^= *((u32int*)&m[12]); + + aes_encrypt(s->ekey, s->rounds, t, t); + } + if(lm > 0){ + for(p = sblock(L, N, i, b, s), x = t; p < &b[lm]; x++, m++, p++){ + *m ^= *p; + *x ^= *m; + } + aes_encrypt(s->ekey, s->rounds, t, t); + } + + for(p = sblock(L, N, 0, b, s), x = t; p < &b[M]; x++, p++) + *x ^= *p; + + return memcmp(m, t, M) != 0; +} --- /sys/src/libsec/port/mkfile Thu May 15 00:45:59 2014 +++ /sys/src/libsec/port/mkfile Thu May 15 00:45:59 2014 @@ -3,7 +3,7 @@ LIB=/$objtype/lib/libsec.a CFILES = des.c desmodes.c desECB.c desCBC.c des3ECB.c des3CBC.c\ - aes.c blowfish.c \ + aes.c aesccm blowfish.c \ hmac.c md5.c md5block.c md4.c sha1.c sha1block.c\ sha2_64.c sha2_128.c sha2block64.c sha2block128.c\ sha1pickle.c md5pickle.c\ --- /sys/include/libsec.h Thu May 15 00:45:59 2014 +++ /sys/include/libsec.h Thu May 15 00:45:59 2014 @@ -41,6 +41,9 @@ void aesCTRdecrypt(uchar *p, int len, AESstate *s); void aesCTRencrypt(uchar *p, int len, AESstate *s); +void aesCCMencrypt(int, int, uchar*, uchar *, int, uchar*, int, AESstate*); +int aesCCMdecrypt(int, int, uchar*, uchar *, int, uchar*, int, AESstate*); + void setupAESXCBCstate(AESstate *s); uchar* aesXCBCmac(uchar *p, int len, AESstate *s);