Commit | Line | Data |
---|---|---|
ea054059 MW |
1 | /* -*-c-*- |
2 | * | |
3 | * The CMAC message-authentication code | |
4 | * | |
5 | * (c) 2017 Straylight/Edgeware | |
6 | */ | |
7 | ||
8 | /*----- Licensing notice --------------------------------------------------* | |
9 | * | |
10 | * This file is part of Catacomb. | |
11 | * | |
12 | * Catacomb is free software; you can redistribute it and/or modify | |
13 | * it under the terms of the GNU Library General Public License as | |
14 | * published by the Free Software Foundation; either version 2 of the | |
15 | * License, or (at your option) any later version. | |
16 | * | |
17 | * Catacomb is distributed in the hope that it will be useful, | |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | * GNU Library General Public License for more details. | |
21 | * | |
22 | * You should have received a copy of the GNU Library General Public | |
23 | * License along with Catacomb; if not, write to the Free | |
24 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, | |
25 | * MA 02111-1307, USA. | |
26 | */ | |
27 | ||
28 | /*----- Notes on CMAC -----------------------------------------------------* | |
29 | * | |
30 | * CMAC was designed in 2003 by Tetsu Iwata and Kaoru Kurosawa as a reliable | |
31 | * general purpose message-authentication code based on CBC-MAC. CBC-MAC's | |
32 | * deficiencies have been well known since at least 2000 when Bellare, | |
33 | * Kilian, and Rogaway proved its security on constant-length messages. | |
34 | * Black and Rogaway in 2000 described a number of three-key constructions | |
35 | * for extending CBC-MAC's domain securely to arbitrary strings, culminating | |
36 | * in a mode they named `XCBC', which uses a blockcipher key and two XOR | |
37 | * masks. Iwata and Kurosawa's original proposal, named `OMAC', refined XCBC | |
38 | * by deriving the masks from the key, producing a `one-key MAC'. Bellare, | |
39 | * Rogaway, and Wagner slightly simplified the way the masks were derived | |
40 | * when they used OMAC as a part of their EAX authenticated-encryption mode, | |
41 | * and this change was adopted by NIST when they standardized OMAC, under the | |
42 | * name `CMAC', in SP800-38B. | |
43 | * | |
44 | * NIST specify CMAC only for 64- and 128-bit blockciphers. This | |
45 | * implementation extends it to other lengths in the obvious way. | |
46 | */ | |
47 | ||
48 | #ifndef CATACOMB_CMAC_H | |
49 | #define CATACOMB_CMAC_H | |
50 | ||
51 | #ifdef __cplusplus | |
52 | extern "C" { | |
53 | #endif | |
54 | ||
55 | /*----- Header files ------------------------------------------------------*/ | |
56 | ||
57 | #include <stddef.h> | |
58 | ||
59 | #include <mLib/bits.h> | |
60 | ||
61 | #ifndef CATACOMB_GMAC_H | |
62 | # include "gmac.h" | |
63 | #endif | |
64 | ||
65 | #ifndef CATACOMB_RSVR_H | |
66 | # include "rsvr.h" | |
67 | #endif | |
68 | ||
69 | /*----- Low-level OMAC declarations ---------------------------------------*/ | |
70 | ||
71 | /* --- @OMAC_DECL@ --- * | |
72 | * | |
73 | * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher | |
74 | * | |
75 | * Use: Defines low-level implementation for the OMAC message- | |
76 | * authentication mode. | |
77 | */ | |
78 | ||
79 | #define OMAC_DECL(PRE, pre) \ | |
80 | \ | |
81 | /* Buffering policy for OMAC. */ \ | |
82 | extern const rsvr_policy pre##_omacpolicy; \ | |
83 | \ | |
84 | /* --- @pre_omacmasks@ --- * \ | |
85 | * \ | |
86 | * Arguments: @pre_ctx *k@ = pointer to expanded blockcipher key \ | |
87 | * @uint32 *m0, *m1@ = buffers to store the masks \ | |
88 | * \ | |
89 | * Returns: --- \ | |
90 | * \ | |
91 | * Use: Initialize the OMAC masks. The mask buffers are \ | |
92 | * @PRE_BLKSZ/4@ words long. The mmask @m0@ is applied to \ | |
93 | * messages which are a whole number of blocks long; @m1@ \ | |
94 | * is applied to messages with an incomplete final block, \ | |
95 | * following the 10* padding. \ | |
96 | */ \ | |
97 | \ | |
98 | extern void pre##_omacmasks(pre##_ctx */*k*/, \ | |
99 | uint32 */*m0*/, uint32 */*m1*/); \ | |
100 | \ | |
101 | /* --- @pre_omacdone@ --- * \ | |
102 | * \ | |
103 | * Arguments: @pre_ctx *k@ = pointer to expanded blockcipher key \ | |
104 | * @const uint32 *m0, *m1@ = masks \ | |
105 | * @uint32 *a@ = accumulator state to update \ | |
106 | * @octet *p@ = pointer to input buffer (clobbered) \ | |
107 | * @unsigned n@ = size of input buffer (no more than \ | |
108 | * @PRE_BLKSZ@) \ | |
109 | * \ | |
110 | * Returns: --- \ | |
111 | * \ | |
112 | * Use: Update and finalize the OMAC hash state with the last \ | |
113 | * few bytes of input. The final tag is left in @a@. \ | |
114 | */ \ | |
115 | \ | |
116 | extern void pre##_omacdone(pre##_ctx */*k*/, \ | |
117 | const uint32 */*m0*/, const uint32 */*m1*/, \ | |
118 | uint32 */*a*/, octet */*p*/, unsigned /*n*/); | |
119 | ||
120 | /*----- Macros ------------------------------------------------------------*/ | |
121 | ||
122 | /* --- @CMAC_DECL@ --- * | |
123 | * | |
124 | * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher | |
125 | * | |
126 | * Use: Creates declarations for CMAC message-authentication mode. | |
127 | */ | |
128 | ||
129 | #define CMAC_DECL(PRE, pre) \ | |
130 | \ | |
131 | OMAC_DECL(PRE, pre) \ | |
132 | \ | |
133 | typedef struct pre##_cmackey { \ | |
134 | pre##_ctx ctx; /* Underlying cipher context */ \ | |
135 | uint32 m0[PRE##_BLKSZ/4], m1[PRE##_BLKSZ/4]; /* Final block masks */ \ | |
136 | } pre##_cmackey; \ | |
137 | \ | |
138 | typedef struct pre##_cmacctx { \ | |
139 | pre##_cmackey k; /* Processed key material */ \ | |
140 | uint32 a[PRE##_BLKSZ/4]; /* Chaining state */ \ | |
141 | octet b[PRE##_BLKSZ]; /* Input buffer */ \ | |
142 | unsigned off; /* Offset into buffered data */ \ | |
143 | } pre##_cmacctx; \ | |
144 | \ | |
145 | /* --- @pre_cmacsetkey@ --- * \ | |
146 | * \ | |
147 | * Arguments: @pre_cmackey *key@ = pointer to CMAC key block \ | |
148 | * @ocnst void *k@ = pointer to key material \ | |
149 | * @size_t ksz@ = size of key material \ | |
150 | * \ | |
151 | * Returns: --- \ | |
152 | * \ | |
153 | * Use: Initializes a CMAC key. This can be used for several \ | |
154 | * MAC operations. \ | |
155 | */ \ | |
156 | \ | |
157 | extern void pre##_cmacsetkey(pre##_cmackey */*key*/, \ | |
158 | const void */*k*/, size_t /*ksz*/); \ | |
159 | \ | |
160 | /* --- @pre##_cmacinit@ --- * \ | |
161 | * \ | |
162 | * Arguments: @pre_cmacctx *ctx@ = pointer to context block \ | |
163 | * @pre_cmackey *k@ = key block \ | |
164 | * \ | |
165 | * Returns: --- \ | |
166 | * \ | |
167 | * Use: Initializes a CMAC context ready to process a message. \ | |
168 | * It's not necessary to keep the key around. \ | |
169 | */ \ | |
170 | \ | |
171 | extern void pre##_cmacinit(pre##_cmacctx */*ctx*/, \ | |
172 | const pre##_cmackey */*k*/); \ | |
173 | \ | |
174 | /* --- @pre_cmachash@ --- * \ | |
175 | * \ | |
176 | * Arguments: @pre_cmacctx *ctx@ = pointer to CMAC context block \ | |
177 | * @ocnst void *p@ = pointer to message buffer \ | |
178 | * @size_t sz@ = size of message buffer \ | |
179 | * \ | |
180 | * Returns: --- \ | |
181 | * \ | |
182 | * Use: Hashes some input data. \ | |
183 | */ \ | |
184 | \ | |
185 | extern void pre##_cmachash(pre##_cmacctx */*ctx*/, \ | |
186 | const void */*p*/, size_t /*sz*/); \ | |
187 | \ | |
188 | /* --- @pre_cmacdone@ --- * \ | |
189 | * \ | |
190 | * Arguments: @pre_cmacctx *ctx@ = pointer to CMAC context block \ | |
191 | * @void *t@ = where to write the tag \ | |
192 | * \ | |
193 | * Returns: --- \ | |
194 | * \ | |
195 | * Use: Finishes a MAC operation and produces the tag. \ | |
196 | */ \ | |
197 | \ | |
198 | extern void pre##_cmacdone(pre##_cmacctx */*ctx*/, void */*t*/); \ | |
199 | \ | |
200 | /* --- Generic MAC interface --- */ \ | |
201 | \ | |
202 | extern const gcmac pre##_cmac; | |
203 | ||
204 | /*----- That's all, folks -------------------------------------------------*/ | |
205 | ||
206 | #ifdef __cplusplus | |
207 | } | |
208 | #endif | |
209 | ||
210 | #endif |