Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions sys/include/libsec.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ typedef struct AESstate AESstate;
struct AESstate
{
ulong setup;
ulong offset;
int rounds;
int keybytes;
uint ctrsz;
Expand All @@ -38,12 +39,28 @@ void aes_decrypt(ulong rk[], int Nr, uchar ct[16], uchar pt[16]);
void setupAESstate(AESstate *s, uchar key[], int keybytes, 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 aesCTRdecrypt(uchar *p, int len, AESstate *s);
void aesCTRencrypt(uchar *p, int len, AESstate *s);

void setupAESXCBCstate(AESstate *s);
uchar* aesXCBCmac(uchar *p, int len, AESstate *s);

typedef struct AESGCMstate AESGCMstate;
struct AESGCMstate
{
AESstate;

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 *p, ulong n, uchar *a, ulong na, uchar tag[16], AESGCMstate *s);
int aesgcm_decrypt(uchar *p, ulong n, uchar *a, ulong na, uchar tag[16], AESGCMstate *s);

/*
* Blowfish Definitions
*/
Expand Down Expand Up @@ -442,3 +459,20 @@ PEMChain*readcertchain(char *filename);
/* 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);

/*
* 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 */
};

mpint *dh_new(DHstate *s, mpint *p, mpint *q, mpint *g);
mpint *dh_finish(DHstate *s, mpint *y);
53 changes: 53 additions & 0 deletions sys/src/9/port/devtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,20 @@ initAESkey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
setupAESstate(s->enckey, p, ea->keylen, iv);
}

static void
initAESGCMkey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
{
/* https://code.9front.org/hg/plan9front/file/808eb735fc45/sys/src/9/port/devtls.c#l1510 */
s->enckey = smalloc(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, iv, ea->ivlen);
}

static void
initclearenc(Encalg *, Secret *s, uchar *, uchar *)
{
Expand All @@ -1502,6 +1516,7 @@ static Encalg encrypttab[] =
{ "3des_ede_cbc", 3 * 8, 8, initDES3key },
{ "aes_128_cbc", 128/8, 16, initAESkey },
{ "aes_256_cbc", 256/8, 16, initAESkey },
{ "aes_128_gcm", 128/8, 4, initAESGCMkey },
{ 0 }
};

Expand Down Expand Up @@ -2093,6 +2108,44 @@ aesdec(Secret *sec, uchar *buf, int n)
return (*sec->unpad)(buf, n, 16);
}

static int
aesgcm_aead_enc(Secret *sec, uchar *a, int na, uchar *reciv, uchar *buf, int n)
{
uchar iv[12];
int i;

memmove(iv, sec->mackey, 4+8);
for(i = 0; i < 8; i++)
iv[4+i] ^= a[i];
memmove(reciv, iv+4, 8);
aesgcm_setiv(sec->enckey, iv, 12);
memset(iv, 0, sizeof iv);
aesgcm_encrypt(buf, n, a, na, buf+n, sec->enckey);
return n + sec->maclen;
}

static int
aesgcm_aead_dec(Secret *sec, uchar *a, int na, uchar *reciv, uchar *buf, int n)
{
uchar iv[12];

n -= sec->maclen;
if(n < 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(buf, n, a, na, buf+n, sec->enckey) != 0)
return -1;
return n;
}

static int
aesgcmdec(Secret *sec, uchar *buf, int n)
{
}

static DigestState*
nomac(uchar *, ulong, uchar *, ulong, uchar *, DigestState *)
{
Expand Down
63 changes: 63 additions & 0 deletions sys/src/libsec/port/aesCFB.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include <u.h>
#include <libc.h>
#include <libsec.h>

void
aesCFBencrypt(uchar *p, int len, AESstate *s)
{
int i;
u32int a, o;

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;
((u32int*)p)[0] = (((u32int*)s->ivec)[0] ^= ((u32int*)p)[0]);
((u32int*)p)[1] = (((u32int*)s->ivec)[1] ^= ((u32int*)p)[1]);
((u32int*)p)[2] = (((u32int*)s->ivec)[2] ^= ((u32int*)p)[2]);
((u32int*)p)[3] = (((u32int*)s->ivec)[3] ^= ((u32int*)p)[3]);
o += 16;
p += 16;
len -= 16;
}
s->offset = o;
}

void
aesCFBdecrypt(uchar *p, int len, AESstate *s)
{
int i;
u32int a, o;

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;
for(i = 0; i < 4; i++){
a = ((u32int*)p)[i];
((u32int*)p)[i] ^= ((u32int*)s->ivec)[i];
((u32int*)s->ivec)[i] = a;
}
o += 16;
p += 16;
len -= 16;
}
s->offset = o;
}
Loading