Line data Source code
1 : /* mac-cmac.c - CMAC glue for MAC API
2 : * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
3 : *
4 : * This file is part of Libgcrypt.
5 : *
6 : * Libgcrypt is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU Lesser general Public License as
8 : * published by the Free Software Foundation; either version 2.1 of
9 : * the License, or (at your option) any later version.
10 : *
11 : * Libgcrypt is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : * GNU Lesser General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public
17 : * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include <config.h>
21 : #include <stdio.h>
22 : #include <stdlib.h>
23 : #include <string.h>
24 : #include <errno.h>
25 :
26 : #include "g10lib.h"
27 : #include "cipher.h"
28 : #include "./mac-internal.h"
29 :
30 :
31 : static int
32 259 : map_mac_algo_to_cipher (int mac_algo)
33 : {
34 259 : switch (mac_algo)
35 : {
36 : default:
37 0 : return GCRY_CIPHER_NONE;
38 : case GCRY_MAC_CMAC_AES:
39 105 : return GCRY_CIPHER_AES;
40 : case GCRY_MAC_CMAC_3DES:
41 73 : return GCRY_CIPHER_3DES;
42 : case GCRY_MAC_CMAC_CAMELLIA:
43 41 : return GCRY_CIPHER_CAMELLIA128;
44 : case GCRY_MAC_CMAC_IDEA:
45 5 : return GCRY_CIPHER_IDEA;
46 : case GCRY_MAC_CMAC_CAST5:
47 5 : return GCRY_CIPHER_CAST5;
48 : case GCRY_MAC_CMAC_BLOWFISH:
49 5 : return GCRY_CIPHER_BLOWFISH;
50 : case GCRY_MAC_CMAC_TWOFISH:
51 5 : return GCRY_CIPHER_TWOFISH;
52 : case GCRY_MAC_CMAC_SERPENT:
53 5 : return GCRY_CIPHER_SERPENT128;
54 : case GCRY_MAC_CMAC_SEED:
55 5 : return GCRY_CIPHER_SEED;
56 : case GCRY_MAC_CMAC_RFC2268:
57 5 : return GCRY_CIPHER_RFC2268_128;
58 : case GCRY_MAC_CMAC_GOST28147:
59 5 : return GCRY_CIPHER_GOST28147;
60 : }
61 : }
62 :
63 :
64 : static gcry_err_code_t
65 124 : cmac_open (gcry_mac_hd_t h)
66 : {
67 : gcry_err_code_t err;
68 : gcry_cipher_hd_t hd;
69 124 : int secure = (h->magic == CTX_MAGIC_SECURE);
70 : int cipher_algo;
71 : unsigned int flags;
72 :
73 124 : cipher_algo = map_mac_algo_to_cipher (h->spec->algo);
74 124 : flags = (secure ? GCRY_CIPHER_SECURE : 0);
75 :
76 124 : err = _gcry_cipher_open_internal (&hd, cipher_algo, GCRY_CIPHER_MODE_CMAC,
77 : flags);
78 124 : if (err)
79 0 : return err;
80 :
81 124 : h->u.cmac.cipher_algo = cipher_algo;
82 124 : h->u.cmac.ctx = hd;
83 124 : h->u.cmac.blklen = _gcry_cipher_get_algo_blklen (cipher_algo);
84 124 : return 0;
85 : }
86 :
87 :
88 : static void
89 124 : cmac_close (gcry_mac_hd_t h)
90 : {
91 124 : _gcry_cipher_close (h->u.cmac.ctx);
92 124 : h->u.cmac.ctx = NULL;
93 124 : }
94 :
95 :
96 : static gcry_err_code_t
97 124 : cmac_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen)
98 : {
99 124 : return _gcry_cipher_setkey (h->u.cmac.ctx, key, keylen);
100 : }
101 :
102 :
103 : static gcry_err_code_t
104 10756 : cmac_reset (gcry_mac_hd_t h)
105 : {
106 10756 : return _gcry_cipher_reset (h->u.cmac.ctx);
107 : }
108 :
109 :
110 : static gcry_err_code_t
111 1245942 : cmac_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
112 : {
113 1245942 : return _gcry_cipher_cmac_authenticate (h->u.cmac.ctx, buf, buflen);
114 : }
115 :
116 :
117 : static gcry_err_code_t
118 10869 : cmac_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t * outlen)
119 : {
120 10869 : if (*outlen > h->u.cmac.blklen)
121 0 : *outlen = h->u.cmac.blklen;
122 10869 : return _gcry_cipher_cmac_get_tag (h->u.cmac.ctx, outbuf, *outlen);
123 : }
124 :
125 :
126 : static gcry_err_code_t
127 102 : cmac_verify (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
128 : {
129 102 : return _gcry_cipher_cmac_check_tag (h->u.cmac.ctx, buf, buflen);
130 : }
131 :
132 :
133 : static unsigned int
134 113 : cmac_get_maclen (int algo)
135 : {
136 113 : return _gcry_cipher_get_algo_blklen (map_mac_algo_to_cipher (algo));
137 : }
138 :
139 :
140 : static unsigned int
141 22 : cmac_get_keylen (int algo)
142 : {
143 22 : return _gcry_cipher_get_algo_keylen (map_mac_algo_to_cipher (algo));
144 : }
145 :
146 :
147 : static gcry_mac_spec_ops_t cmac_ops = {
148 : cmac_open,
149 : cmac_close,
150 : cmac_setkey,
151 : NULL,
152 : cmac_reset,
153 : cmac_write,
154 : cmac_read,
155 : cmac_verify,
156 : cmac_get_maclen,
157 : cmac_get_keylen
158 : };
159 :
160 :
161 : #if USE_BLOWFISH
162 : gcry_mac_spec_t _gcry_mac_type_spec_cmac_blowfish = {
163 : GCRY_MAC_CMAC_BLOWFISH, {0, 0}, "CMAC_BLOWFISH",
164 : &cmac_ops
165 : };
166 : #endif
167 : #if USE_DES
168 : gcry_mac_spec_t _gcry_mac_type_spec_cmac_tripledes = {
169 : GCRY_MAC_CMAC_3DES, {0, 1}, "CMAC_3DES",
170 : &cmac_ops
171 : };
172 : #endif
173 : #if USE_CAST5
174 : gcry_mac_spec_t _gcry_mac_type_spec_cmac_cast5 = {
175 : GCRY_MAC_CMAC_CAST5, {0, 0}, "CMAC_CAST5",
176 : &cmac_ops
177 : };
178 : #endif
179 : #if USE_AES
180 : gcry_mac_spec_t _gcry_mac_type_spec_cmac_aes = {
181 : GCRY_MAC_CMAC_AES, {0, 1}, "CMAC_AES",
182 : &cmac_ops
183 : };
184 : #endif
185 : #if USE_TWOFISH
186 : gcry_mac_spec_t _gcry_mac_type_spec_cmac_twofish = {
187 : GCRY_MAC_CMAC_TWOFISH, {0, 0}, "CMAC_TWOFISH",
188 : &cmac_ops
189 : };
190 : #endif
191 : #if USE_SERPENT
192 : gcry_mac_spec_t _gcry_mac_type_spec_cmac_serpent = {
193 : GCRY_MAC_CMAC_SERPENT, {0, 0}, "CMAC_SERPENT",
194 : &cmac_ops
195 : };
196 : #endif
197 : #if USE_RFC2268
198 : gcry_mac_spec_t _gcry_mac_type_spec_cmac_rfc2268 = {
199 : GCRY_MAC_CMAC_RFC2268, {0, 0}, "CMAC_RFC2268",
200 : &cmac_ops
201 : };
202 : #endif
203 : #if USE_SEED
204 : gcry_mac_spec_t _gcry_mac_type_spec_cmac_seed = {
205 : GCRY_MAC_CMAC_SEED, {0, 0}, "CMAC_SEED",
206 : &cmac_ops
207 : };
208 : #endif
209 : #if USE_CAMELLIA
210 : gcry_mac_spec_t _gcry_mac_type_spec_cmac_camellia = {
211 : GCRY_MAC_CMAC_CAMELLIA, {0, 0}, "CMAC_CAMELLIA",
212 : &cmac_ops
213 : };
214 : #endif
215 : #ifdef USE_IDEA
216 : gcry_mac_spec_t _gcry_mac_type_spec_cmac_idea = {
217 : GCRY_MAC_CMAC_IDEA, {0, 0}, "CMAC_IDEA",
218 : &cmac_ops
219 : };
220 : #endif
221 : #if USE_GOST28147
222 : gcry_mac_spec_t _gcry_mac_type_spec_cmac_gost28147 = {
223 : GCRY_MAC_CMAC_GOST28147, {0, 0}, "CMAC_GOST28147",
224 : &cmac_ops
225 : };
226 : #endif
|