summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
b2de6bd)
We are going to need to distinguish more cases. It was always bad to
have these hardcoded values.
transform_apply_seqrange is, right now, returned even when the problem
is that the packet is recent but is a duplicate. This is wrong.
No functional change.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
typedef bool_t transform_valid_fn(void *st); /* 0: no key; 1: ok */
typedef void transform_delkey_fn(void *st);
typedef void transform_destroyinstance_fn(void *st);
typedef bool_t transform_valid_fn(void *st); /* 0: no key; 1: ok */
typedef void transform_delkey_fn(void *st);
typedef void transform_destroyinstance_fn(void *st);
-/* Returns:
- * 0: all is well
- * 1: for any other problem
- * 2: message decrypted but sequence number was out of range
- */
-typedef uint32_t transform_apply_fn(void *st, struct buffer_if *buf,
- const char **errmsg);
+
+typedef enum {
+ transform_apply_ok = 0, /* all is well (everyone may assume==0) */
+ transform_apply_err = 1, /* any other problem */
+ transform_apply_seqrange = 2,
+ /* message decrypted but sequence number was out of range */
+} transform_apply_return;
+
+typedef transform_apply_return transform_apply_fn(void *st,
+ struct buffer_if *buf, const char **errmsg);
struct transform_inst_if {
void *st;
struct transform_inst_if {
void *st;
}
#define DEFINE_CALL_TRANSFORM(fwdrev) \
}
#define DEFINE_CALL_TRANSFORM(fwdrev) \
-static int call_transform_##fwdrev(struct site *st, \
+static transform_apply_return \
+call_transform_##fwdrev(struct site *st, \
struct transform_inst_if *transform, \
struct buffer_if *buf, \
const char **errmsg) \
{ \
if (!is_transform_valid(transform)) { \
*errmsg="transform not set up"; \
struct transform_inst_if *transform, \
struct buffer_if *buf, \
const char **errmsg) \
{ \
if (!is_transform_valid(transform)) { \
*errmsg="transform not set up"; \
+ return transform_apply_err; \
} \
return transform->fwdrev(transform->st,buf,errmsg); \
}
} \
return transform->fwdrev(transform->st,buf,errmsg); \
}
/* Give the netlink code an opportunity to put its own stuff in the
message (configuration information, etc.) */
buf_prepend_uint32(&st->buffer,LABEL_MSG6);
/* Give the netlink code an opportunity to put its own stuff in the
message (configuration information, etc.) */
buf_prepend_uint32(&st->buffer,LABEL_MSG6);
- int problem = call_transform_forwards(st,transform,
- &st->buffer,&transform_err);
+ transform_apply_return problem =
+ call_transform_forwards(st,transform,
+ &st->buffer,&transform_err);
assert(!problem);
buf_prepend_uint32(&st->buffer,LABEL_MSG6);
buf_prepend_uint32(&st->buffer,st->index);
assert(!problem);
buf_prepend_uint32(&st->buffer,LABEL_MSG6);
buf_prepend_uint32(&st->buffer,st->index);
{
cstring_t transform_err, auxkey_err, newkey_err="n/a";
struct msg0 m;
{
cstring_t transform_err, auxkey_err, newkey_err="n/a";
struct msg0 m;
+ transform_apply_return problem;
if (!unpick_msg0(st,msg0,&m)) return False;
if (!unpick_msg0(st,msg0,&m)) return False;
"peer has used new key","auxiliary key",LOG_SEC);
return True;
}
"peer has used new key","auxiliary key",LOG_SEC);
return True;
}
+ if (problem==transform_apply_seqrange)
goto skew;
buffer_copy(msg0, &st->scratch);
problem = call_transform_reverse(st,st->auxiliary_key.transform,
msg0,&auxkey_err);
goto skew;
buffer_copy(msg0, &st->scratch);
problem = call_transform_reverse(st,st->auxiliary_key.transform,
msg0,&auxkey_err);
slog(st,LOG_DROP,"processing packet which uses auxiliary key");
if (st->auxiliary_is_new) {
/* We previously timed out in state SENTMSG5 but it turns
slog(st,LOG_DROP,"processing packet which uses auxiliary key");
if (st->auxiliary_is_new) {
/* We previously timed out in state SENTMSG5 but it turns
+ if (problem==transform_apply_seqrange)
goto skew;
if (st->state==SITE_SENTMSG5) {
goto skew;
if (st->state==SITE_SENTMSG5) {
activate_new_key(st);
return True; /* do process the data in this packet */
}
activate_new_key(st);
return True; /* do process the data in this packet */
}
+ if (problem==transform_apply_seqrange)
-static uint32_t transform_forward(void *sst, struct buffer_if *buf,
- const char **errmsg)
+static transform_apply_return transform_forward(void *sst,
+ struct buffer_if *buf, const char **errmsg)
{
struct transform_inst *ti=sst;
uint8_t *padp;
{
struct transform_inst *ti=sst;
uint8_t *padp;
-static uint32_t transform_reverse(void *sst, struct buffer_if *buf,
- const char **errmsg)
+static transform_apply_return transform_reverse(void *sst,
+ struct buffer_if *buf, const char **errmsg)
{
struct transform_inst *ti=sst;
uint8_t *padp;
{
struct transform_inst *ti=sst;
uint8_t *padp;
if (buf->size < 4 + 16 + 16) {
*errmsg="msg too short";
if (buf->size < 4 + 16 + 16) {
*errmsg="msg too short";
+ return transform_apply_err;
/* Assert bufsize is multiple of blocksize */
if (buf->size&0xf) {
*errmsg="msg not multiple of cipher blocksize";
/* Assert bufsize is multiple of blocksize */
if (buf->size&0xf) {
*errmsg="msg not multiple of cipher blocksize";
+ return transform_apply_err;
}
serpentbe_encrypt(&ti->cryptkey,iv,iv);
for (n=buf->start; n<buf->start+buf->size; n+=16)
}
serpentbe_encrypt(&ti->cryptkey,iv,iv);
for (n=buf->start; n<buf->start+buf->size; n+=16)
serpentbe_encrypt(&ti->mackey,macacc,macacc);
if (!consttime_memeq(macexpected,macacc,16)!=0) {
*errmsg="invalid MAC";
serpentbe_encrypt(&ti->mackey,macacc,macacc);
if (!consttime_memeq(macexpected,macacc,16)!=0) {
*errmsg="invalid MAC";
+ return transform_apply_err;
}
/* PKCS5, stolen from IWJ */
}
/* PKCS5, stolen from IWJ */
padlen=*padp;
if (!padlen || (padlen > PKCS5_MASK+1)) {
*errmsg="pkcs5: invalid length";
padlen=*padp;
if (!padlen || (padlen > PKCS5_MASK+1)) {
*errmsg="pkcs5: invalid length";
+ return transform_apply_err;
}
buf_unappend(buf,padlen-1);
}
buf_unappend(buf,padlen-1);
#define KEYED_CHECK do{ \
if (!ti->keyed) { \
*errmsg="transform unkeyed"; \
#define KEYED_CHECK do{ \
if (!ti->keyed) { \
*errmsg="transform unkeyed"; \
+ return transform_apply_err; \
} else { \
/* Too much skew */ \
*errmsg="seqnum: too much skew"; \
} else { \
/* Too much skew */ \
*errmsg="seqnum: too much skew"; \
+ return transform_apply_seqrange; \
} \
if ((p)->dedupe) { \
recvbitmap_type recvbit=(uint32_t)1 << skew; \
if (ti->recvbitmap & recvbit) { \
*errmsg="seqnum: duplicate"; \
} \
if ((p)->dedupe) { \
recvbitmap_type recvbit=(uint32_t)1 << skew; \
if (ti->recvbitmap & recvbit) { \
*errmsg="seqnum: duplicate"; \
+ return transform_apply_seqrange; \
} \
ti->recvbitmap |= recvbit; \
} \
} \
ti->recvbitmap |= recvbit; \
} \
-static uint32_t transform_forward(void *sst, struct buffer_if *buf,
- const char **errmsg)
+static transform_apply_return transform_forward(void *sst,
+ struct buffer_if *buf, const char **errmsg)
{
struct transform_inst *ti=sst;
{
struct transform_inst *ti=sst;
-static uint32_t transform_reverse(void *sst, struct buffer_if *buf,
- const char **errmsg)
+static transform_apply_return transform_reverse(void *sst,
+ struct buffer_if *buf, const char **errmsg)
{
struct transform_inst *ti=sst;
{
struct transform_inst *ti=sst;
if (!ok) {
TEAX_DEBUG(0,0);
*errmsg="EAX decryption failed";
if (!ok) {
TEAX_DEBUG(0,0);
*errmsg="EAX decryption failed";
+ return transform_apply_err;
}
assert(buf->size >= (int)ti->p.tag_length);
buf->size -= ti->p.tag_length;
}
assert(buf->size >= (int)ti->p.tag_length);
buf->size -= ti->p.tag_length;
too_short:
*errmsg="ciphertext or plaintext too short";
too_short:
*errmsg="ciphertext or plaintext too short";
+ return transform_apply_err;
}
static struct transform_inst_if *transform_create(void *sst)
}
static struct transform_inst_if *transform_create(void *sst)