/* * PKCS#5 padding mechanism for udp tunnel * * mechanism: pkcs5 * arguments: block size to pad to, must be power of 2 and <=128 * * restrictions: none * encoding: append between 1 and n bytes, all of the same value being * the number of bytes appended */ /* * This file is part of ipif, part of userv-utils * * Copyright 1996-2013 Ian Jackson * Copyright 1998 David Damerell * Copyright 1999,2003 * Chancellor Masters and Scholars of the University of Cambridge * Copyright 2010 Tony Finch * * This 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. * * This program 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 * along with userv-utils; if not, see http://www.gnu.org/licenses/. */ #include "forwarder.h" struct mechdata { unsigned mask; }; static unsigned long setup(struct mechdata **md_r) { struct mechdata *md; unsigned long blocksize; XMALLOC(md); blocksize= getarg_ulong(); md->mask= blocksize - 1; arg_assert(!(md->mask & blocksize)); arg_assert(blocksize <= 255); *md_r= md; return blocksize; } static void mes_pkcs5(struct mechdata **md_r, int *maxprefix_io, int *maxsuffix_io) { unsigned long blocksize; blocksize= setup(md_r); *maxsuffix_io += blocksize + 1; } static void mds_pkcs5(struct mechdata **md_r) { setup(md_r); } static void menc_pkcs5(struct mechdata *md, struct buffer *buf) { unsigned char *pad; int padlen; /* eg with blocksize=4 mask=3 mask+2=5 */ /* msgsize 20 21 22 23 24 */ padlen= md->mask - buf->size; /* -17 -18 -19 -16 -17 */ padlen &= md->mask; /* 3 2 1 0 3 */ padlen++; /* 4 3 2 1 4 */ pad= buf_append(buf,padlen); memset(pad,padlen,padlen); } static const char *mdec_pkcs5(struct mechdata *md, struct buffer *buf) { unsigned char *padp; unsigned padlen; int i; BUF_UNAPPEND(padp,buf,1); padlen= *padp; if (!padlen || (padlen > md->mask+1)) return "invalid length"; BUF_UNAPPEND(padp,buf,padlen-1); for (i=0; i