/*
* eax-transform.c: EAX-Serpent bulk data transformation
+ */
+/*
+ * This file is part of secnet.
+ * See README for full list of copyright holders.
*
+ * secnet is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * secnet is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 3 along with secnet; if not, see
+ * https://www.gnu.org/licenses/gpl.html.
+ */
+/*
* We use EAX with the following parameters:
*
* Plaintext:
#define SEQLEN 4
struct transform_params {
- uint32_t max_seq_skew, tag_length, padding_mask;
+ SEQNUM_PARAMS_FIELDS;
+ uint32_t tag_length, padding_mask;
};
struct transform {
struct transform_inst {
struct transform_inst_if ops;
struct transform_params p;
- unsigned keyed:1;
/* remaining valid iff keyed */
unsigned direction:1;
- uint32_t sendseq;
- uint32_t lastrecvseq;
+ SEQNUM_KEYED_FIELDS;
struct keyInstance key;
uint8_t info_b[BLOCK_SIZE], info_p[BLOCK_SIZE];
};
TEAX_DEBUG(hash_out+32,8);
ti->direction=direction;
- ti->sendseq=get_uint32(hash_out+32+direction*4);
- ti->lastrecvseq=get_uint32(hash_out+32+!direction*4);
serpent_makekey(&ti->key, 32*8, hash_out);
eax_setup(ti);
- ti->keyed=True;
+ SEQNUM_KEYED_INIT(get_uint32(hash_out+32+!direction*4),
+ get_uint32(hash_out+32+direction*4));
return True;
}
ti->keyed=False;
}
-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;
TEAX_DEBUG(buf->start,buf->size);
- memcpy(buf_append(buf,SEQLEN), nonce, SEQLEN);
+ BUF_ADD_BYTES(append,buf,nonce,SEQLEN);
TEAX_DEBUG(nonce,SEQLEN);
return 0;
}
-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;
if (!ok) {
TEAX_DEBUG(0,0);
*errmsg="EAX decryption failed";
- return 1;
+ return transform_apply_err;
}
assert(buf->size >= (int)ti->p.tag_length);
buf->size -= ti->p.tag_length;
size_t padlen = *padp;
if (!buf_unappend(buf,padlen-1)) goto too_short;
- SEQNUM_CHECK(seqnum, ti->p.max_seq_skew);
+ SEQNUM_CHECK(seqnum, &ti->p);
TEAX_DEBUG(buf->start,buf->size);
too_short:
*errmsg="ciphertext or plaintext too short";
- return 1;
+ return transform_apply_err;
}
static struct transform_inst_if *transform_create(void *sst)
item_t *item;
dict_t *dict;
- st=safe_malloc(sizeof(*st),"eax-serpent");
+ NEW(st);
st->cl.description="eax-serpent";
st->cl.type=CL_TRANSFORM;
st->cl.apply=NULL;
cfgfatal(loc,"eax-serpent","parameter must be a dictionary\n");
dict=item->data.dict;
- st->p.max_seq_skew=dict_read_number(dict, "max-sequence-skew",
- False, "eax-serpent", loc, 10);
+ SET_CAPAB_BIT(CAPAB_BIT_EAXSERPENT);
+
+ SEQNUM_PARAMS_INIT(dict,&st->p,"eax-serpent",loc);
st->p.tag_length=dict_read_number(dict, "tag-length-bytes",
False, "eax-serpent", loc, 128/8);
padding_round = 1;
st->p.padding_mask = padding_round-1;
- st->ops.max_start_pad=0;
- st->ops.max_end_pad= padding_round + st->p.tag_length + SEQLEN;
+ update_max_start_pad(&transform_max_start_pad, 0);
st->ops.keylen=0;
st->ops.create=transform_create;