84f87e82 |
1 | /* |
2 | * PKCS#5 padding |
3 | * |
4 | * arguments: block size to pad to, must be power of 2 |
5 | * |
6 | * encoding: append between 1 and n bytes, all of the same value being |
7 | * the number of bytes appended |
8 | */ |
9 | |
aaa9ab3a |
10 | #include "forwarder.h" |
84f87e82 |
11 | |
12 | struct mechdata { |
13 | unsigned mask; |
14 | }; |
15 | |
16 | static unsigned long setup(struct mechdata **md_r) { |
17 | struct mechdata *md; |
18 | unsigned long blocksize; |
19 | |
20 | XMALLOC(md); |
21 | |
22 | blocksize= getarg_ulong(); |
23 | md->mask= blocksize - 1; |
24 | arg_assert(!md->mask & blocksize); |
25 | arg_assert(blocksize <= 255); |
26 | |
27 | *md_r= md; |
28 | return blocksize; |
29 | } |
30 | |
31 | static void mes_pkcs5(struct mechdata **md_r, int *maxprefix_io, int *maxsuffix_io) { |
32 | unsigned long blocksize; |
33 | |
34 | blocksize= setup(md_r); |
35 | *maxsuffix_io += blocksize + 1; |
36 | } |
37 | |
38 | static void mds_pkcs5(struct mechdata **md_r) { |
39 | setup(md_r); |
40 | } |
41 | |
42 | static void menc_pkcs5(struct mechdata *md, struct buffer *buf) { |
43 | unsigned char *pad; |
44 | int padlen; |
45 | |
46 | /* eg with blocksize=4 mask=3 mask+2=5 */ |
47 | /* msgsize 20 21 22 23 24 */ |
48 | padlen= md->mask - buf->size; /* -17 -18 -19 -16 -17 */ |
49 | padlen &= md->mask; /* 3 2 1 0 3 */ |
50 | padlen++; /* 4 3 2 1 4 */ |
51 | |
52 | pad= buf_append(buf,padlen); |
53 | memset(pad,padlen,padlen); |
54 | } |
55 | |
56 | static const char *mdec_pkcs5(struct mechdata *md, struct buffer *buf) { |
57 | unsigned char *padp; |
58 | unsigned padlen; |
59 | int i; |
60 | |
61 | BUF_UNPREPEND(padp,buf,1); |
62 | padlen= *padp; |
63 | if (!padlen || (padlen & ~md->mask)) return "invalid length"; |
64 | |
65 | BUF_UNPREPEND(padp,buf,padlen-1); |
66 | for (i=0; i<padlen-1; i++) |
67 | if (*++padp != padlen) return "corrupted padding"; |
68 | |
69 | return 0; |
70 | } |
71 | |
72 | STANDARD_MECHANISMLIST("pkcs5",pkcs5) |