chiark
/
gitweb
/
~ian
/
secnet.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Import release 0.1.15
[secnet.git]
/
transform.c
diff --git
a/transform.c
b/transform.c
index f94f5ae5571a19073017a3c8d5c16bb380c91beb..53ff448b3f58383670bb0c60108dd05bf288eb8e 100644
(file)
--- a/
transform.c
+++ b/
transform.c
@@
-8,13
+8,26
@@
the packets sent over the wire. */
#include <stdio.h>
the packets sent over the wire. */
#include <stdio.h>
+#include <string.h>
#include "secnet.h"
#include "util.h"
#include "serpent.h"
#include "secnet.h"
#include "util.h"
#include "serpent.h"
+#include "unaligned.h"
/* Required key length in bytes */
#define REQUIRED_KEYLEN ((512+64+32)/8)
/* Required key length in bytes */
#define REQUIRED_KEYLEN ((512+64+32)/8)
+#ifdef WORDS_BIGENDIAN
+static inline uint32_t byteswap(uint32_t a)
+{
+ return
+ ((a&0x000000ff)<<24) |
+ ((a&0x0000ff00)<<8) |
+ ((a&0x00ff0000)>>8) |
+ ((a&0xff000000)>>24);
+}
+#endif
+
struct transform {
closure_t cl;
uint32_t line;
struct transform {
closure_t cl;
uint32_t line;
@@
-41,7
+54,7
@@
static bool_t transform_setkey(void *sst, uint8_t *key, uint32_t keylen)
struct transform_inst *ti=sst;
if (keylen<REQUIRED_KEYLEN) {
struct transform_inst *ti=sst;
if (keylen<REQUIRED_KEYLEN) {
- Message(M_ERR
OR
,"transform_create: insufficient key material supplied "
+ Message(M_ERR,"transform_create: insufficient key material supplied "
"(need %d bytes, got %d)\n",REQUIRED_KEYLEN,keylen);
return False;
}
"(need %d bytes, got %d)\n",REQUIRED_KEYLEN,keylen);
return False;
}
@@
-58,9
+71,9
@@
static bool_t transform_setkey(void *sst, uint8_t *key, uint32_t keylen)
serpent_makekey(&ti->cryptkey,256,key);
serpent_makekey(&ti->mackey,256,key+32);
serpent_makekey(&ti->cryptkey,256,key);
serpent_makekey(&ti->mackey,256,key+32);
- ti->cryptiv=
*(uint32_t *)(key+64
);
- ti->maciv=
*(uint32_t *)(key+68
);
- ti->sendseq=
*(uint32_t *)(key+72
);
+ ti->cryptiv=
ntohl(*(uint32_t *)(key+64)
);
+ ti->maciv=
ntohl(*(uint32_t *)(key+68)
);
+ ti->sendseq=
ntohl(*(uint32_t *)(key+72)
);
ti->lastrecvseq=ti->sendseq;
ti->keyed=True;
ti->lastrecvseq=ti->sendseq;
ti->keyed=True;
@@
-77,7
+90,7
@@
static void transform_delkey(void *sst)
}
static uint32_t transform_forward(void *sst, struct buffer_if *buf,
}
static uint32_t transform_forward(void *sst, struct buffer_if *buf,
- char **errmsg)
+ c
onst c
har **errmsg)
{
struct transform_inst *ti=sst;
uint8_t *padp;
{
struct transform_inst *ti=sst;
uint8_t *padp;
@@
-93,7
+106,7
@@
static uint32_t transform_forward(void *sst, struct buffer_if *buf,
}
/* Sequence number */
}
/* Sequence number */
-
*(uint32_t *)buf_prepend(buf,4)=htonl(
ti->sendseq);
+
buf_prepend_uint32(buf,
ti->sendseq);
ti->sendseq++;
/* PKCS5, stolen from IWJ */
ti->sendseq++;
/* PKCS5, stolen from IWJ */
@@
-119,13
+132,26
@@
static uint32_t transform_forward(void *sst, struct buffer_if *buf,
block encrypted once again. */
for (n=(uint32_t *)buf->start; n<(uint32_t *)(buf->start+buf->size); n+=4)
{
block encrypted once again. */
for (n=(uint32_t *)buf->start; n<(uint32_t *)(buf->start+buf->size); n+=4)
{
+#ifdef WORDS_BIGENDIAN
+ macplain[0]=macacc[0]^byteswap(n[0]);
+ macplain[1]=macacc[1]^byteswap(n[1]);
+ macplain[2]=macacc[2]^byteswap(n[2]);
+ macplain[3]=macacc[3]^byteswap(n[3]);
+#else
macplain[0]=macacc[0]^n[0];
macplain[1]=macacc[1]^n[1];
macplain[2]=macacc[2]^n[2];
macplain[3]=macacc[3]^n[3];
macplain[0]=macacc[0]^n[0];
macplain[1]=macacc[1]^n[1];
macplain[2]=macacc[2]^n[2];
macplain[3]=macacc[3]^n[3];
+#endif
serpent_encrypt(&ti->mackey,macplain,macacc);
}
serpent_encrypt(&ti->mackey,macacc,macacc);
serpent_encrypt(&ti->mackey,macplain,macacc);
}
serpent_encrypt(&ti->mackey,macacc,macacc);
+#ifdef WORDS_BIGENDIAN
+ macacc[0]=byteswap(macacc[0]);
+ macacc[1]=byteswap(macacc[1]);
+ macacc[2]=byteswap(macacc[2]);
+ macacc[3]=byteswap(macacc[3]);
+#endif
memcpy(buf_append(buf,16),macacc,16);
/* Serpent-CBC. We expand the ID as for CBCMAC, do the encryption,
memcpy(buf_append(buf,16),macacc,16);
/* Serpent-CBC. We expand the ID as for CBCMAC, do the encryption,
@@
-137,24
+163,45
@@
static uint32_t transform_forward(void *sst, struct buffer_if *buf,
/* CBC: each block is XORed with the previous encrypted block (or the IV)
before being encrypted. */
p=iv;
/* CBC: each block is XORed with the previous encrypted block (or the IV)
before being encrypted. */
p=iv;
+#ifdef WORDS_BIGENDIAN
+ /* This counters the byteswap() in the first half of the loop, which in
+ turn counters the byteswap() in the second half of the loop. Ick. */
+ iv[0]=byteswap(iv[0]);
+ iv[1]=byteswap(iv[1]);
+ iv[2]=byteswap(iv[2]);
+ iv[3]=byteswap(iv[3]);
+#endif
for (n=(uint32_t *)buf->start; n<(uint32_t *)(buf->start+buf->size); n+=4)
{
for (n=(uint32_t *)buf->start; n<(uint32_t *)(buf->start+buf->size); n+=4)
{
+#ifdef WORDS_BIGENDIAN
+ /* Think of this as byteswap(p[x])^byteswap(n[x]) */
+ n[0]=byteswap(p[0]^n[0]);
+ n[1]=byteswap(p[1]^n[1]);
+ n[2]=byteswap(p[2]^n[2]);
+ n[3]=byteswap(p[3]^n[3]);
+#else
n[0]=p[0]^n[0];
n[1]=p[1]^n[1];
n[2]=p[2]^n[2];
n[3]=p[3]^n[3];
n[0]=p[0]^n[0];
n[1]=p[1]^n[1];
n[2]=p[2]^n[2];
n[3]=p[3]^n[3];
+#endif
serpent_encrypt(&ti->cryptkey,n,n);
serpent_encrypt(&ti->cryptkey,n,n);
+#ifdef WORDS_BIGENDIAN
+ n[0]=byteswap(n[0]);
+ n[1]=byteswap(n[1]);
+ n[2]=byteswap(n[2]);
+ n[3]=byteswap(n[3]);
+#endif
p=n;
}
p=n;
}
-
*(uint32_t *)buf_prepend(buf,4)=ti->cryptiv
;
+
buf_prepend_uint32(buf,ti->cryptiv)
;
ti->cryptiv++;
ti->cryptiv++;
-
return 0;
}
static uint32_t transform_reverse(void *sst, struct buffer_if *buf,
return 0;
}
static uint32_t transform_reverse(void *sst, struct buffer_if *buf,
- char **errmsg)
+ c
onst c
har **errmsg)
{
struct transform_inst *ti=sst;
uint8_t *padp;
{
struct transform_inst *ti=sst;
uint8_t *padp;
@@
-173,19
+220,36
@@
static uint32_t transform_reverse(void *sst, struct buffer_if *buf,
return 1;
}
return 1;
}
+
/* CBC */
memset(iv,0,16);
/* CBC */
memset(iv,0,16);
- iv[0]=*(uint32_t *)buf_unprepend(buf,4);
+ iv[0]=buf_unprepend_uint32(buf);
+ /* Assert bufsize is multiple of blocksize */
+ if (buf->size&0xf) {
+ *errmsg="msg not multiple of cipher blocksize";
+ }
serpent_encrypt(&ti->cryptkey,iv,iv);
serpent_encrypt(&ti->cryptkey,iv,iv);
- /* XXX assert bufsize is multiple of blocksize */
for (n=(uint32_t *)buf->start; n<(uint32_t *)(buf->start+buf->size); n+=4)
{
for (n=(uint32_t *)buf->start; n<(uint32_t *)(buf->start+buf->size); n+=4)
{
+#ifdef WORDS_BIGENDIAN
+ n[0]=byteswap(n[0]);
+ n[1]=byteswap(n[1]);
+ n[2]=byteswap(n[2]);
+ n[3]=byteswap(n[3]);
+#endif
pct[0]=n[0]; pct[1]=n[1]; pct[2]=n[2]; pct[3]=n[3];
serpent_decrypt(&ti->cryptkey,n,n);
pct[0]=n[0]; pct[1]=n[1]; pct[2]=n[2]; pct[3]=n[3];
serpent_decrypt(&ti->cryptkey,n,n);
+#ifdef WORDS_BIGENDIAN
+ n[0]=byteswap(iv[0]^n[0]);
+ n[1]=byteswap(iv[1]^n[1]);
+ n[2]=byteswap(iv[2]^n[2]);
+ n[3]=byteswap(iv[3]^n[3]);
+#else
n[0]=iv[0]^n[0];
n[1]=iv[1]^n[1];
n[2]=iv[2]^n[2];
n[3]=iv[3]^n[3];
n[0]=iv[0]^n[0];
n[1]=iv[1]^n[1];
n[2]=iv[2]^n[2];
n[3]=iv[3]^n[3];
+#endif
iv[0]=pct[0]; iv[1]=pct[1]; iv[2]=pct[2]; iv[3]=pct[3];
}
iv[0]=pct[0]; iv[1]=pct[1]; iv[2]=pct[2]; iv[3]=pct[3];
}
@@
-199,13
+263,26
@@
static uint32_t transform_reverse(void *sst, struct buffer_if *buf,
block encrypted once again. */
for (n=(uint32_t *)buf->start; n<(uint32_t *)(buf->start+buf->size); n+=4)
{
block encrypted once again. */
for (n=(uint32_t *)buf->start; n<(uint32_t *)(buf->start+buf->size); n+=4)
{
+#ifdef WORDS_BIGENDIAN
+ macplain[0]=macacc[0]^byteswap(n[0]);
+ macplain[1]=macacc[1]^byteswap(n[1]);
+ macplain[2]=macacc[2]^byteswap(n[2]);
+ macplain[3]=macacc[3]^byteswap(n[3]);
+#else
macplain[0]=macacc[0]^n[0];
macplain[1]=macacc[1]^n[1];
macplain[2]=macacc[2]^n[2];
macplain[3]=macacc[3]^n[3];
macplain[0]=macacc[0]^n[0];
macplain[1]=macacc[1]^n[1];
macplain[2]=macacc[2]^n[2];
macplain[3]=macacc[3]^n[3];
+#endif
serpent_encrypt(&ti->mackey,macplain,macacc);
}
serpent_encrypt(&ti->mackey,macacc,macacc);
serpent_encrypt(&ti->mackey,macplain,macacc);
}
serpent_encrypt(&ti->mackey,macacc,macacc);
+#ifdef WORDS_BIGENDIAN
+ macacc[0]=byteswap(macacc[0]);
+ macacc[1]=byteswap(macacc[1]);
+ macacc[2]=byteswap(macacc[2]);
+ macacc[3]=byteswap(macacc[3]);
+#endif
if (memcmp(macexpected,macacc,16)!=0) {
*errmsg="invalid MAC";
return 1;
if (memcmp(macexpected,macacc,16)!=0) {
*errmsg="invalid MAC";
return 1;
@@
-230,12
+307,12
@@
static uint32_t transform_reverse(void *sst, struct buffer_if *buf,
/* Sequence number must be within max_skew of lastrecvseq; lastrecvseq
is only allowed to increase. */
/* Sequence number must be within max_skew of lastrecvseq; lastrecvseq
is only allowed to increase. */
- seqnum=
ntohl(*(uint32_t *)buf_unprepend(buf,4)
);
+ seqnum=
buf_unprepend_uint32(buf
);
skew=seqnum-ti->lastrecvseq;
skew=seqnum-ti->lastrecvseq;
- if (skew<
10
) {
+ if (skew<
0x8fffffff
) {
/* Ok */
ti->lastrecvseq=seqnum;
/* Ok */
ti->lastrecvseq=seqnum;
- } else if ((0-skew)<
10
) {
+ } else if ((0-skew)<
ti->max_skew
) {
/* Ok */
} else {
/* Too much skew */
/* Ok */
} else {
/* Too much skew */
@@
-328,14
+405,14
@@
void transform_module(dict_t *dict)
ciphertext[2]!=0x83C31E69 ||
ciphertext[1]!=0xec52bd82 ||
ciphertext[0]!=0x27a46120) {
ciphertext[2]!=0x83C31E69 ||
ciphertext[1]!=0xec52bd82 ||
ciphertext[0]!=0x27a46120) {
- fatal("transform_module: serpent failed self-test (encrypt)
\n
");
+ fatal("transform_module: serpent failed self-test (encrypt)");
}
serpent_decrypt(&k,ciphertext,plaintext);
if (plaintext[0]!=0 ||
plaintext[1]!=1 ||
plaintext[2]!=2 ||
plaintext[3]!=3) {
}
serpent_decrypt(&k,ciphertext,plaintext);
if (plaintext[0]!=0 ||
plaintext[1]!=1 ||
plaintext[2]!=2 ||
plaintext[3]!=3) {
- fatal("transform_module: serpent failed self-test (decrypt)
\n
");
+ fatal("transform_module: serpent failed self-test (decrypt)");
}
add_closure(dict,"serpent256-cbc",transform_apply);
}
add_closure(dict,"serpent256-cbc",transform_apply);