| 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 |