2 * Written in 2013 by Gregor Pintar <grpintar@gmail.com>
4 * To the extent possible under law, the author(s) have dedicated
5 * all copyright and related and neighboring rights to this software
6 * to the public domain worldwide.
8 * This software is distributed without any warranty.
10 * You should have received a copy of the CC0 Public Domain Dedication.
11 * If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
19 #include <kripto/loadstore.h>
20 #include <kripto/memwipe.h>
21 #include <kripto/block.h>
22 #include <kripto/mac.h>
23 #include <kripto/desc/mac.h>
24 #include <kripto/object/mac.h>
26 #include <kripto/mac/xcbc.h>
30 struct kripto_mac_object obj
;
40 static int xcbc_init(kripto_mac
*s
, unsigned int r
)
45 for(i
= 0; i
< s
->len
; i
++) s
->buf
[i
] = 1;
46 kripto_block_encrypt(s
->block
, s
->buf
, s
->buf
);
49 for(i
= 0; i
< s
->len
; i
++) s
->k2
[i
] = 2;
50 kripto_block_encrypt(s
->block
, s
->k2
, s
->k2
);
53 for(i
= 0; i
< s
->len
; i
++) s
->k3
[i
] = 3;
54 kripto_block_encrypt(s
->block
, s
->k3
, s
->k3
);
56 s
->block
= kripto_block_recreate(s
->block
, r
, s
->buf
, s
->len
);
57 if(!s
->block
) return -1;
59 memset(s
->buf
, 0, s
->len
);
66 static void xcbc_input(kripto_mac
*s
, const void *in
, size_t len
)
70 for(i
= 0; i
< len
; i
++)
72 s
->buf
[s
->i
++] ^= CU8(in
)[i
];
76 kripto_block_encrypt(s
->block
, s
->buf
, s
->buf
);
82 static void xcbc_tag(kripto_mac
*s
, void *tag
, unsigned int len
)
95 for(i
= 0; i
< s
->len
; i
++)
96 s
->buf
[i
] ^= s
->k3
[i
];
101 for(i
= 0; i
< s
->len
; i
++)
102 s
->buf
[i
] ^= s
->k2
[i
];
105 kripto_block_encrypt(s
->block
, s
->buf
, s
->buf
);
111 for(i
= 0; i
< len
; i
++)
113 assert(s
->i
< s
->len
);
114 U8(tag
)[i
] = s
->buf
[s
->i
++];
118 static void xcbc_destroy(kripto_mac
*s
)
120 kripto_block_destroy(s
->block
);
122 kripto_memwipe(s
, sizeof(kripto_mac
) + s
->len
* 3);
128 kripto_mac_desc desc
;
129 const kripto_block_desc
*block
;
132 #define EXT(X) ((const struct ext *)(X))
134 static kripto_mac
*xcbc_create
136 const kripto_mac_desc
*desc
,
139 unsigned int key_len
,
147 s
= malloc(sizeof(kripto_mac
) + desc
->maxtag
* 3);
151 s
->len
= desc
->maxtag
;
152 s
->buf
= (uint8_t *)s
+ sizeof(kripto_mac
);
153 s
->k2
= s
->buf
+ s
->len
;
154 s
->k3
= s
->k2
+ s
->len
;
155 s
->block
= kripto_block_create(EXT(desc
)->block
, r
, key
, key_len
);
171 static kripto_mac
*xcbc_recreate
176 unsigned int key_len
,
182 s
->block
= kripto_block_recreate(s
->block
, r
, key
, key_len
);
183 if(!s
->block
) goto err
;
185 if(xcbc_init(s
, r
)) goto err
;
190 kripto_memwipe(s
, sizeof(kripto_mac
) + s
->obj
.desc
->maxtag
* 3);
195 kripto_mac_desc
*kripto_mac_xcbc(const kripto_block_desc
*block
)
199 s
= malloc(sizeof(struct ext
));
204 s
->desc
.create
= &xcbc_create
;
205 s
->desc
.recreate
= &xcbc_recreate
;
206 s
->desc
.input
= &xcbc_input
;
207 s
->desc
.tag
= &xcbc_tag
;
208 s
->desc
.destroy
= &xcbc_destroy
;
209 s
->desc
.maxtag
= kripto_block_size(block
);
210 s
->desc
.maxkey
= kripto_block_maxkey(block
);
212 return (kripto_mac_desc
*)s
;